問題描述
當作為參數傳遞時,PHP 如何解釋和評估函數和匿名函數? (How does PHP interpret and evaluate function and anonymous function when passed as an argument?)
我是一名經驗豐富的 PHP 開發人員,我已經知道什麼是函數以及什麼是匿名函數。我也知道匿名函數和 PHP 或其他語言中的函數的用途。我也知道函數和匿名函數的區別。
anynonymous 函數的定義見:http://php.net/manual/en/functions.anonymous.php
匿名函數的用例在這裡:為什麼以及如何在 PHP 中使用匿名函數?
但我的問題是 PHP 如何將函數解釋/評估為參數?
考慮以下示例:
<?php
function callFunction($function)
{
$function();
}
//normal function
function test()
{
echo "here";
}
//anonymous function
$function = function () {
echo 'here';
};
//call normal function test
callFunction('test');
//call anonymous function $function
callFunction($function);
在上面的示例中,兩個函數都產生相同的輸出。
但我想知道 PHP 如何在 callFunction
方法中執行/解釋/評估這兩個函數。我研究了相同的搜索引擎,但無法找到可以正確解釋相同內容的確切答案。請幫助我理解這兩種情況。
參考解法
方法 1:
Let's see the two cases separately:
<?php
function callFunction($function)
{
$function();
}
//normal function
function test()
{
echo "here";
}
//call normal function test
callFunction('test');
In this case the actual parameter for callFunction
is the value "here", so a string
value is passed. However, the syntax of PHP supports the concept of making it a dynamic function call: variable functions.
PHP supports the concept of variable functions. This means that if a variable name has parentheses appended to it, PHP will look for a function with the same name as whatever the variable evaluates to, and will attempt to execute it. Among other things, this can be used to implement callbacks, function tables, and so forth.
Now, onto the second case:
<?php
function callFunction($function)
{
$function();
}
//anonymous function
$function = function () {
echo 'here';
};
//call anonymous function $function
callFunction($function);
In this case $function
is a Closure, as it is mentioned in the reference you linked. It is the implemented way of the function object concept in PHP. The received Closure is then executed with the parentheses operator.
You may even enforce the parameter typing in order to separate it into two different cases with type hinting:
// NOTE: string type hinting only available since PHP7
function callFunction_string(string $function)
{
$function();
}
function callFunction_closure(Closure $function)
{
$function();
}
So basically the type of the parameter received by callFunction
is entirely different (string vs. Closure), however the PHP syntax is the same for both of them to execute a function call. (It's not a coincidence, it was designed like that.)
Note: similar solutions are widespread in programming languages, even in strongly typed languages like C++: just look at how function pointers, functors and lamda objects can be passed as an ‑ templated ‑ argument to a function, and then executed with the parentheses operator.
(by Chetan Ameta、mcserep)