PHP Conference Japan 2024

匿名函式

匿名函式,也稱為 閉包,允許建立沒有指定名稱的函式。它們最常用於作為 可呼叫 參數的值,但它們還有許多其他用途。

匿名函式是使用 Closure 類別實作的。

範例 #1 匿名函式範例

<?php
echo preg_replace_callback('~-([a-z])~', function ($match) {
return
strtoupper($match[1]);
},
'hello-world');
// 輸出 helloWorld
?>

閉包也可以用作變數的值;PHP 會自動將此類運算式轉換為 Closure 內部類別的實例。將閉包賦值給變數會使用與任何其他賦值相同的語法,包括尾隨分號

範例 #2 匿名函式變數賦值範例

<?php
$greet
= function($name) {
printf("Hello %s\r\n", $name);
};

$greet('World');
$greet('PHP');
?>

閉包也可以從父作用域繼承變數。任何此類變數都必須傳遞給 use 語言結構。從 PHP 7.1 開始,這些變數不得包含 超全域變數$this 或與參數同名的變數。函式的傳回型別宣告必須放置在 use 子句之後

範例 #3 從父作用域繼承變數

<?php
$message
= 'hello';

// 沒有 "use"
$example = function () {
var_dump($message);
};
$example();

// 繼承 $message
$example = function () use ($message) {
var_dump($message);
};
$example();

// 繼承的變數值來自函式定義時,而不是呼叫時
$message = 'world';
$example();

// 重置訊息
$message = 'hello';

// 透過引用繼承
$example = function () use (&$message) {
var_dump($message);
};
$example();

// 父作用域中變更的值
// 會反映在函式呼叫內部
$message = 'world';
$example();

// 閉包也可以接受常規引數
$example = function ($arg) use ($message) {
var_dump($arg . ' ' . $message);
};
$example("hello");

// 傳回型別宣告在 use 子句之後
$example = function () use ($message): string {
return
"hello $message";
};
var_dump($example());
?>

上述範例將輸出類似以下的內容

Notice: Undefined variable: message in /example.php on line 6
NULL
string(5) "hello"
string(5) "hello"
string(5) "hello"
string(5) "world"
string(11) "hello world"
string(11) "hello world"

從 PHP 8.0.0 開始,範圍繼承的變數清單可以包含尾隨逗號,這將會被忽略。

從父作用域繼承變數與使用全域變數不同。全域變數存在於全域作用域中,無論執行哪個函式,全域作用域都相同。閉包的父作用域是宣告閉包的函式(不一定是呼叫它的函式)。請參閱以下範例

範例 #4 閉包和作用域

<?php
// 一個基本的購物車,包含已加入的產品列表
// 以及每個產品的數量。包含一個方法,使用
// 閉包作為回呼函數來計算購物車中物品的總價。
class Cart
{
const
PRICE_BUTTER = 1.00;
const
PRICE_MILK = 3.00;
const
PRICE_EGGS = 6.95;

protected
$products = array();

public function
add($product, $quantity)
{
$this->products[$product] = $quantity;
}

public function
getQuantity($product)
{
return isset(
$this->products[$product]) ? $this->products[$product] :
FALSE;
}

public function
getTotal($tax)
{
$total = 0.00;

$callback =
function (
$quantity, $product) use ($tax, &$total)
{
$pricePerItem = constant(__CLASS__ . "::PRICE_" .
strtoupper($product));
$total += ($pricePerItem * $quantity) * ($tax + 1.0);
};

array_walk($this->products, $callback);
return
round($total, 2);
}
}

$my_cart = new Cart;

// 將一些商品加入購物車
$my_cart->add('butter', 1);
$my_cart->add('milk', 3);
$my_cart->add('eggs', 6);

// 列印總價,加上 5% 的銷售稅。
print $my_cart->getTotal(0.05) . "\n";
// 結果是 54.29
?>

範例 #5 自動綁定 $this

<?php

class Test
{
public function
testing()
{
return function() {
var_dump($this);
};
}
}

$object = new Test;
$function = $object->testing();
$function();

?>

上面的範例將會輸出

object(Test)#1 (0) {
}

當在類別的上下文中宣告時,目前的類別會自動綁定到它,使 $this 在函數的範圍內可用。如果不需要自動綁定目前類別,則可以使用靜態匿名函數

靜態匿名函數

匿名函數可以靜態宣告。這可以防止它們自動綁定目前的類別。物件也不能在執行時綁定到它們。

範例 #6 嘗試在靜態匿名函數內使用 $this

<?php

class Foo
{
function
__construct()
{
$func = static function() {
var_dump($this);
};
$func();
}
};
new
Foo();

?>

上面的範例將會輸出

Notice: Undefined variable: this in %s on line %d
NULL

範例 #7 嘗試將物件綁定到靜態匿名函數

<?php

$func
= static function() {
// 函數主體
};
$func = $func->bindTo(new stdClass);
$func();

?>

上面的範例將會輸出

Warning: Cannot bind an instance to a static closure in %s on line %d

變更記錄

版本 描述
8.3.0 魔術方法建立的閉包可以接受具名參數。
7.1.0 匿名函數可能不會關閉超全域變數$this,或任何與參數同名的變數。

備註

注意 可以從閉包內使用 func_num_args()func_get_arg()func_get_args()

新增註解

使用者貢獻的註解 20 個註解

325
orls
14 年前
當將變數「匯入」到閉包的範圍時,請小心 — 很容易忽略/忘記它們實際上是被*複製*到閉包的範圍中,而不僅僅是使其可用。

因此,如果您的閉包關心它們隨著時間的推移的內容,您需要明確地按引用傳遞它們

<?php
$result
= 0;

$one = function()
{
var_dump($result); };

$two = function() use ($result)
{
var_dump($result); };

$three = function() use (&$result)
{
var_dump($result); };

$result++;

$one(); // 輸出 NULL:$result 不在範圍內
$two(); // 輸出 int(0):$result 已被複製
$three(); // 輸出 int(1)
?>

另一個不太簡單的物件範例(我實際上被絆倒的地方)

<?php
//提前設定變數
$myInstance = null;

$broken = function() uses ($myInstance)
{
if(!empty(
$myInstance)) $myInstance->doSomething();
};

$working = function() uses (&$myInstance)
{
if(!empty(
$myInstance)) $myInstance->doSomething();
}

//$myInstance 可能被實例化,也可能沒有
if(SomeBusinessLogic::worked() == true)
{
$myInstance = new myClass();
}

$broken(); // 永遠不會做任何事:$myInstance 在此閉包內將永遠為 null。
$working(); // 如果 $myInstance 被實例化,將會呼叫 doSomething

?>
33
erolmon dot kskn at gmail dot com
9 年前
<?php
/*
(string) $name 你將添加到類別中的函式名稱。
用法:$Foo->add(function(){},$name);
這會在 Foo 類別中新增一個 public 函式。
*/
class Foo
{
public function
add($func,$name)
{
$this->{$name} = $func;
}
public function
__call($func,$arguments){
call_user_func_array($this->{$func}, $arguments);
}
}
$Foo = new Foo();
$Foo->add(function(){
echo
"Hello World";
},
"helloWorldFunction");
$Foo->add(function($parameterone){
echo
$parameterone;
},
"exampleFunction");
$Foo->helloWorldFunction(); /* 輸出:Hello World */
$Foo->exampleFunction("Hello PHP"); /* 輸出:Hello PHP */
?>
29
cHao
10 年前
以防你感到好奇(因為我很好奇),匿名函式可以像具名函式一樣回傳參考。只需像對具名函式一樣使用 `&` ... 在 `function` 關鍵字之後(以及在不存在的名稱之前)。

<?php
$value
= 0;
$fn = function &() use (&$value) { return $value; };

$x =& $fn();
var_dump($x, $value); // 'int(0)', 'int(0)'
++$x;
var_dump($x, $value); // 'int(1)', 'int(1)'
1
Hayley Watson
6 個月前
如果您有一個儲存在物件屬性中的閉包(或其它可呼叫的物件),並且想要呼叫它,您可以使用括號來消除它與方法呼叫之間的歧義

<?php
class Test
{
public
$callable;

function
__construct()
{
$this->callable = function($a) { return $a + 2; };
}
}

$t = new Test;

echo (
$t->callable)(40);
?>
13
dexen dot devries at gmail dot com
6 年前
每個 Lambda 實例都有自己的靜態變數實例。這為出色的事件處理常式、累積器等提供了基礎。

使用 function() { ... }; 表達式建立新的 Lambda 會建立其靜態變數的新實例。將 Lambda 指派給變數不會建立新實例。Lambda 是類別 Closure 的物件,而將 Lambda 指派給變數具有與將物件實例指派給變數相同的語意。

範例腳本:$a 和 $b 具有單獨的靜態變數實例,因此產生不同的輸出。但是 $b 和 $c 共用它們的靜態變數實例 - 因為 $c 指的是與 $b 相同的類別 Closure 的物件 - 因此產生相同的輸出。

#!/usr/bin/env php
<?php

function generate_lambda() : Closure
{
# 建立新的 Lambda 實例
return function($v = null) {
static
$stored;
if (
$v !== null)
$stored = $v;
return
$stored;
};
}

$a = generate_lambda(); # 建立靜態變數的新實例
$b = generate_lambda(); # 建立靜態變數的新實例
$c = $b; # 使用與 $b 相同的靜態變數實例

$a('test AAA');
$b('test BBB');
$c('test CCC'); # 這會覆寫 $b 所持有的內容,因為它指的是相同的物件

var_dump([ $a(), $b(), $c() ]);
?>

此測試腳本輸出
array(3) {
[0]=>
string(8) "test AAA"
[1]=>
string(8) "test CCC"
[2]=>
string(8) "test CCC"
}
15
a dot schaffhirt at sedna-soft dot de
15 年前
當在類別中使用匿名函式作為屬性時,請注意有三個名稱範圍:一個用於常數、一個用於屬性,以及一個用於方法。這表示您可以同時為常數、屬性和方法使用相同的名稱。

由於從 PHP 5.3.0 開始,屬性也可以是匿名函式,因此當它們共用相同的名稱時,會產生一個奇怪之處,但這並不表示會有任何衝突。

考慮以下範例

<?php
class MyClass {
const
member = 1;

public
$member;

public function
member () {
return
"method 'member'";
}

public function
__construct () {
$this->member = function () {
return
"anonymous function 'member'";
};
}
}

header("Content-Type: text/plain");

$myObj = new MyClass();

var_dump(MyClass::member); // int(1)
var_dump($myObj->member); // object(Closure)#2 (0) {}
var_dump($myObj->member()); // string(15) "method 'member'"
$myMember = $myObj->member;
var_dump($myMember()); // string(27) "anonymous function 'member'"
?>

這表示,常規的方法調用會如預期般運作,並且與之前相同。相反地,匿名函式必須先擷取到變數中(就像屬性一樣),然後才能被調用。

誠摯的問候,
9
ayon at hyurl dot com
7 年前
呼叫匿名函式遞迴的一種方法是使用 USE 關鍵字並傳遞對函式本身的參考

<?php
$count
= 1;
$add = function($count) use (&$add){
$count += 1;
if(
$count < 10) $count = $add($count); //遞迴呼叫
return $count;
};
echo
$add($count); //將會如預期輸出 10
?>
8
rob at ubrio dot us
15 年前
您可以使用 __call() 方法來呼叫受保護的成員 - 類似於您在 Ruby 中使用 send 的方式。

<?php

class Fun
{
protected function
debug($message)
{
echo
"DEBUG: $message\n";
}

public function
yield_something($callback)
{
return
$callback("Soemthing!!");
}

public function
having_fun()
{
$self =& $this;
return
$this->yield_something(function($data) use (&$self)
{
$self->debug("Doing stuff to the data");
// 對 $data 執行某些操作
$self->debug("Finished doing stuff with the data.");
});
}

// 啊哈!
public function __call($method, $args = array())
{
if(
is_callable(array($this, $method)))
return
call_user_func_array(array($this, $method), $args);
}
}

$fun = new Fun();
echo
$fun->having_fun();

?>
10
mail at mkharitonov dot net
10 年前
PHP 和 JavaScript 閉包的一些比較。

=== 範例 1(傳值) ===
PHP 程式碼
<?php
$aaa
= 111;
$func = function() use($aaa){ print $aaa; };
$aaa = 222;
$func(); // 輸出 "111"
?>

類似的 JavaScript 程式碼
<script type="text/javascript">
var aaa = 111;
var func = (function(aaa){ return function(){ alert(aaa); } })(aaa);
aaa = 222;
func(); // 輸出 "111"
</script>

請注意,以下程式碼與先前的程式碼不同
<script type="text/javascript">
var aaa = 111;
var bbb = aaa;
var func = function(){ alert(bbb); };
aaa = 222;
func(); // 輸出 "111",但前提是 "bbb" 在函式宣告後沒有被更改

// 而且這個技巧在迴圈中不起作用
var functions = [];
for (var i = 0; i < 2; i++)
{
var i2 = i;
functions.push(function(){ alert(i2); });
}
functions[0](); // 輸出 "1",錯誤!
functions[1](); // 輸出 "1",正確
</script>

=== 範例 2(傳參考) ===
PHP 程式碼
<?php
$aaa
= 111;
$func = function() use(&$aaa){ print $aaa; };
$aaa = 222;
$func(); // 輸出 "222"
?>

類似的 JavaScript 程式碼
<script type="text/javascript">
var aaa = 111;
var func = function(){ alert(aaa); };
aaa = 222; // 輸出 "222"
func();
</script>
10
simon at generalflows dot com
13 年前
<?php

/*
* 一個範例展示如何使用閉包來實作類似 Python 的裝飾器模式。
*
* 我的目標是讓你可以使用任何其他函式來裝飾一個函式,然後直接呼叫被裝飾的函式:
*
* 定義函式:$foo = function($a, $b, $c, ...) {...}
* 定義裝飾器:$decorator = function($func) {...}
* 裝飾它:$foo = $decorator($foo)
* 呼叫它:$foo($a, $b, $c, ...)
*
* 這個範例展示了一個服務的身份驗證裝飾器,使用一個簡單的模擬會話和模擬服務。
*/

session_start();

/*
* 定義一個範例裝飾器。裝飾器函式應該採用以下形式:
* $decorator = function($func) {
* return function() use $func) {
* // 執行某些操作,然後在需要時呼叫被裝飾的函式:
* $args = func_get_args($func);
* call_user_func_array($func, $args);
* // 執行其他操作。
* };
* };
*/
$authorise = function($func) {
return function() use (
$func) {
if (
$_SESSION['is_authorised'] == true) {
$args = func_get_args($func);
call_user_func_array($func, $args);
}
else {
echo
"拒絕存取";
}
};
};

/*
* 定義一個要被裝飾的函式,在這個範例中是一個需要授權的模擬服務。
*/
$service = function($foo) {
echo
"服務回傳: $foo";
};

/*
* 裝飾它。確保你用被裝飾的函式取代原始函式參考;也就是說,只使用 $authorise($service) 不會起作用,所以要使用
* $service = $authorise($service)
*/
$service = $authorise($service);

/*
* 建立模擬授權,呼叫服務;應該會得到
* '服務回傳: test 1'。
*/
$_SESSION['is_authorised'] = true;
$service('test 1');

/*
* 移除模擬授權,呼叫服務;應該會得到 '拒絕存取'。
*/
$_SESSION['is_authorised'] = false;
$service('test 2');

?>
13
john at binkmail dot com
7 年前
2017 年效能基準測試!

我決定比較在每次迴圈迭代中儲存的單一閉包與不斷建立相同的匿名閉包。我使用 2016 年 12 月的 PHP 7.0.14 嘗試了 1000 萬次迴圈迭代。結果

儲存在變數中並重複使用的單一儲存閉包(10000000 次迭代):1.3874590396881 秒

每次都建立新的匿名閉包(10000000 次迭代):2.8460240364075 秒

換句話說,在 1000 萬次迭代的過程中,每次迭代都重新建立閉包只在執行時間中增加了總共「1.459 秒」。所以這表示在我的 7 年舊雙核筆記型電腦上,每次建立新的匿名閉包約需 146 奈秒。我猜想 PHP 保留了匿名函式的快取「範本」,因此不需要太多時間來建立閉包的新實例!

因此,你**不需要**擔心在緊湊迴圈中不斷地重新建立匿名閉包!至少在 PHP 7 中不需要!絕對**沒有必要**將實例儲存在變數中並重複使用它。而且不受此限制是一件好事,因為這意味著你可以隨心所欲地在它們重要的位置使用匿名函式,而不是在程式碼的其他地方定義它們。:-)
8
derkontrollfreak+9hy5l at gmail dot com
10 年前
請注意,自 PHP 5.4 以來,將一個在相同物件範圍中實例化的閉包註冊為物件屬性,會建立循環參考,這會阻止立即物件銷毀
<?php

class Test
{
private
$closure;

public function
__construct()
{
$this->closure = function () {
};
}

public function
__destruct()
{
echo
"已銷毀\n";
}
}

new
Test;
echo
"已完成\n";

/*
* PHP 5.3 中的結果:
* ------------------
* 已銷毀
* 已完成
*
* 自 PHP 5.4 以來的結果:
* ---------------------
* 已完成
* 已銷毀
*/

?>

為了規避這個問題,你可以在靜態方法中實例化閉包
<?php

public function __construct()
{
$this->closure = self::createClosure();
}

public static function
createClosure()
{
return function () {
};
}

?>
11
toonitw at gmail dot com
6 年前
自 PHP 7.0 起,你可以使用 IIFE(立即呼叫函式運算式),方法是用 () 包裹你的匿名函式。

<?php
$type
= 'number';
var_dump( ...( function() use ($type) {
if (
$type=='number') return [1,2,3];
else if (
$type=='alphabet') return ['a','b','c'];
} )() );
?>
5
jake dot tunaley at berkeleyit dot com
5 年前
請注意在分配給靜態變數的匿名函式中使用 $this。

<?php
class Foo {
public function
bar() {
static
$anonymous = null;
if (
$anonymous === null) {
// 運算式不允許作為靜態初始化器,這裡是一個變通辦法
$anonymous = function () {
return
$this;
};
}
return
$anonymous();
}
}

$a = new Foo();
$b = new Foo();
var_dump($a->bar() === $a); // True
var_dump($b->bar() === $a); // 也為 True
?>

在靜態匿名函式中,$this 將是首次呼叫該方法的任何物件實例的值。

要獲得你可能預期的行為,你需要將 $this 上下文傳遞到函式中。

<?php
class Foo {
public function
bar() {
static
$anonymous = null;
if (
$anonymous === null) {
// 運算式不允許作為靜態初始化器的替代方案
$anonymous = function (self $thisObj) {
return
$thisObj;
};
}
return
$anonymous($this);
}
}

$a = new Foo();
$b = new Foo();
var_dump($a->bar() === $a); // True
var_dump($b->bar() === $a); // False
?>
1
Hayley Watson
1 年前
「如果不需要自動綁定目前的類別,則可以使用靜態匿名函式來代替。」

您不希望自動綁定的主要原因是,只要為匿名函式建立的 Closure 物件存在,它就會保留對產生它的物件的引用,阻止物件被銷毀,即使該物件在程式中的其他任何地方都不再存在,即使函式本身沒有使用 $this。

<?php

class Foo
{
public function
__construct(private string $id)
{
echo
"Creating Foo " . $this->id, "\n";
}
public function
gimme_function()
{
return function(){};
}
public function
gimme_static_function()
{
return static function(){};
}
public function
__destruct()
{
echo
"Destroying Foo " . $this->id, "\n";
}
}

echo
"當最後一個引用被移除時,物件就會被銷毀。\n";
$t = new Foo('Alice');
$t = new Foo('Bob'); // 導致 Alice 被銷毀。
// 現在銷毀 Bob。
unset($t);
echo
"---\n";

echo
"非靜態匿名函式會保留對建立它的物件的引用。\n";
$u = new Foo('Carol');
$ufn = $u->gimme_function();
$u = new Foo('Daisy'); // 不會導致 Carol 被銷毀,
// 因為 $ufn 所持有的函式中仍然有一個對它的引用。
unset($u); // 導致 Daisy 被銷毀。
echo "---\n"; // 注意到 Carol 尚未被銷毀。

echo "靜態匿名函式不會保留對建立它的物件的引用。\n";
$v = new Foo('Eve');
$vfn = $v->gimme_static_function();
$v = new Foo('Farid'); // $vfn 持有的函式沒有
// 持有對 Eve 的引用,所以 Eve 在這裡被銷毀。
unset($v); // 銷毀 Farid
echo "---\n";
// 然後程式結束,丟棄對任何仍然存活的物件的引用
// (特別是 Carol)。
?>

因為 $ufn 在程式結束時仍然存活,所以 Carol 也存活了下來。 $vfn 在程式結束時也仍然存活,但它包含的函式被宣告為靜態,所以沒有保留對 Eve 的引用。

因此,保留對其他已死亡物件的引用的匿名函式是潛在的記憶體洩漏來源。如果函式不需要產生它的物件,將其宣告為靜態可以防止它導致物件超出其有用性而存活。
7
kdelux at gmail dot com
14 年前
這是一個定義然後在 Closure 函式中使用變數 ($this) 的一個範例。下面的程式碼探討了所有用法,並顯示了限制。

此程式碼片段中最有用的工具是 requesting_class() 函式,它會告訴您哪個類別負責執行目前的 Closure()。

概述
-----------------------
成功找到呼叫物件的參考。
成功呼叫 $this(__invoke);
成功引用 $$this->name;
成功呼叫 call_user_func(array($this, 'method'))

失敗:透過 $this-> 參考任何內容
失敗:$this->name = '';
失敗:$this->delfect();

<?php



function requesting_class()
{
foreach(
debug_backtrace(true) as $stack){
if(isset(
$stack['object'])){
return
$stack['object'];
}
}

}






class
Person
{
public
$name = '';
public
$head = true;
public
$feet = true;
public
$deflected = false;

function
__invoke($p){ return $this->$p; }
function
__toString(){ return 'this'; } // 測試參考

function __construct($name){ $this->name = $name; }
function
deflect(){ $this->deflected = true; }

public function
shoot()
{
// 如果定義了 customAttack,則使用它作為射擊結果。否則射擊腳
if(is_callable($this->customAttack)){
return
call_user_func($this->customAttack);
}

$this->feet = false;
}
}

$p = new Person('Bob');


$p->customAttack =
function(){

echo
$this; // Notice: Undefined variable: this

#$this = new Class() // FATAL ERROR

// 分配變數 '$this' 的技巧
extract(array('this' => requesting_class())); // 確定哪個類別負責呼叫 Closure

var_dump( $this ); // 被動參考有效
var_dump( $$this ); // 新增到類別:function __toString(){ return 'this'; }

$name = $this('name'); // 成功
echo $name; // 輸出:Bob
echo '<br />';
echo $
$this->name;

call_user_func_array(array($this, 'deflect'), array()); // 成功呼叫

#$this->head = 0; //** FATAL ERROR: Using $this when not in object context
$$this->head = 0; // 成功設定值

};

print_r($p);

$p->shoot();

print_r($p);


die();

?>
4
mike at borft dot student dot utwente dot nl
12 年前
由於可以將閉包賦值給類別變數,因此很遺憾無法直接呼叫它們。也就是說,以下程式碼無法運作
<?php
class foo {

public
test;

public function
__construct(){
$this->test = function($a) {
print
"$a\n";
};
}
}

$f = new foo();

$f->test();
?>

但是,可以使用魔術方法 __call 來實現
<?php
class foo {

public
test;

public function
__construct(){
$this->test = function($a) {
print
"$a\n";
};
}

public function
__call($method, $args){
if (
$this->{$method} instanceof Closure ) {
return
call_user_func_array($this->{$method},$args);
} else {
return
parent::__call($method, $args);
}
}
}
$f = new foo();
$f->test();
?>

希望這對某人有幫助 ;)
3
匿名
15 年前
如果你想檢查你處理的是否確實是閉包,而不是字串或陣列回呼,你可以這樣做

<?php
$isAClosure
= is_callable($thing) && is_object($thing);
?>
1
petersenc at gmail dot com
4 個月前
截至 PHP 8.3.9,PHP 不允許在 use 語句中進行型別提示。考慮以下 Laravel 路由

Route::get('/tags/{tag}', function (string $tag) use ($posts): View {
$tagPosts = $posts->filter(
function (Post $post) use ($tag): bool {
return in_array($tag, $post->tags);
}
);

return view('tags.show', [
'posts' => $tagPosts,
'tag' => $tag
]);
});

正如你所看到的,我可以透過在閉包中對參數和回傳類型進行型別提示,使程式碼更加冗長。然而,use 不允許型別提示。
-2
gabriel dot totoliciu at ddsec dot net
14 年前
如果你想建立一個遞迴閉包,你需要這樣寫

$some_var1="1";
$some_var2="2";

function($param1, $param2) use ($some_var1, $some_var2)
{

// 這裡有一些程式碼

call_user_func(__FUNCTION__, $other_param1, $other_param2);

// 這裡有一些程式碼

}

如果你需要透過參照傳遞值,你應該查看

https://php.dev.org.tw/manual/en/function.call-user-func.php
https://php.dev.org.tw/manual/en/function.call-user-func-array.php

如果你想知道是否仍然可以使用 call_user_func 存取 $some_var1 和 $some_var2,答案是肯定的,它們是可用的。
To Top