当作为参数传递时,PHP 如何解释和评估函数和匿名函数?

How does PHP interpret and evaluate function and anonymous function when passed as an argument?

我是PHP的经验开发者,我已经知道什么是函数,什么是匿名函数。我也知道匿名函数和PHP或其他语言中的函数有什么用。我也知道函数和匿名函数的区别

匿名函数的定义可在以下位置找到: http://php.net/manual/en/functions.anonymous.php

我在这里得到了匿名函数的用例: Why and how do you use anonymous functions in PHP?

但我的问题是 PHP interpret/evaluate 如何作为参数发挥作用?

考虑以下示例:

<?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 execute/interpret/evaluate 这两个函数在 callFunction 方法中是如何起作用的。我在搜索引擎上进行了相同的研究,但无法找到可以正确解释相同内容的确切答案。请帮助我理解这两种情况。

我们分别来看两种情况:

<?php

function callFunction($function)
{
    $function();
}

//normal function
function test()
{
    echo "here";
}

//call normal function test
callFunction('test');

在这种情况下,callFunction 的实际参数是值 "here",因此传递了 string 值。但是,PHP 的语法支持使其成为动态函数调用的概念: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.

现在,进入第二种情况:

<?php

function callFunction($function)
{
    $function();
}

//anonymous function
$function = function () {
    echo 'here';
};

//call anonymous function $function
callFunction($function);

在这种情况下 $function 是一个 闭包 ,正如参考文献 you linked 中提到的那样。是PHP中函数对象概念的实现方式。然后使用括号运算符执行接收到的闭包。

您甚至可以强制输入参数,以便使用 type hinting 将其分为两种不同的情况:

// NOTE: string type hinting only available since PHP7
function callFunction_string(string $function)
{
    $function();
}

function callFunction_closure(Closure $function)
{
    $function();
}

所以基本上 callFunction 接收的参数类型完全不同(字符串与闭包),但是 PHP 语法对于它们执行函数调用是相同的。 (不是巧合,就是这么设计的。)

注意:类似的解决方案在编程语言中很普遍,甚至在像 C++ 这样的强类型语言中也是如此:看看函数指针、仿函数和 lamda 对象如何作为模板化参数传递给函数,然后用括号运算符执行。