为什么应该将函数分配给变量?

Her*_*ool 3 php anonymous-function

在阅读php.net 上的匿名函数条目并查看提供的示例时,我遇到了本节,其中提到了这些函数的第二个用例:

闭包也可以用作变量的值。

我想知道为什么应该将方法分配给变量?我在这里试图了解这种方法的优点是什么:

$greet = function($name)
{
    echo "Hello $name";
};

$greet('World');
$greet('PHP');
Run Code Online (Sandbox Code Playgroud)

像这样的一块:

function greet($name) 
{
    echo "Hello $name";
}
greet('World');
greet('PHP');
Run Code Online (Sandbox Code Playgroud)

这有道理吗?这只是编写一段代码的另一种方式吗?或者,在某些情况下,在更高级的设计中,它将为更具描述性的代码库构建空间?

Dha*_*man 5

这是一个很好的问题。匿名函数的特点是它们通常应该是匿名的。当您将它们分配给变量时,您给了它们一个名称,但这违背了目的。

在一个简单的示例中,它们的工作方式与命名函数相同:

function named($a) {
    echo 'This is '.$a;
}

$unnamed = function ($a) {
    echo 'This is '.$a;
};

function caller($callee, string $name) {
    $callee($name);
}

caller('named', 'named');
caller($unnamed, 'unnamed');
Run Code Online (Sandbox Code Playgroud)

唯一的区别是,$callee一次是字符串,一次是函数。

区别:

想象一下,您有一个场景,您希望将当前作用域捕获到一个函数中,并将其传递到另一个函数中以作为回调执行。

$v1 = 2;
$a = function() use($v1) { return $v1; };
// or 
$a = fn() => $v1;
$v1 = 4;

function named($callback) {
    $v1 = 3;
    echo $callback();
}

named($a); //output is 2
Run Code Online (Sandbox Code Playgroud)

对于普通函数,您必须将值作为参数传递给函数。在调用函数时,值发生了变化,这意味着您需要在定义函数时自己捕获该值。

您可以将闭包分配给变量这一事实并不意味着您必须这样做。这意味着该函数可以作为一等公民传递。

例如,考虑以下代码,它捕获B类中的私有属性并将其在闭包内部传递给A类:

class A {
    private $someVar = 'Hello world!';

    public function __construct($callback) {
        $callback();
    }
}

class B {
    private $someVar = 'Bogus!';

    public function createCallback() {
        return function () {
            echo $this->someVar;
        };
    }
}

$b = new B();
new A($b->createCallback()); // echo Bogus!
Run Code Online (Sandbox Code Playgroud)