关闭

闭包是一种无法访问外部作用域的匿名函数

在定义匿名函数时,你正在为该函数创建命名空间。它目前只能访问该命名空间。

$externalVariable = "Hello";
$secondExternalVariable = "Foo"; 
$myFunction = function() { 
  
  var_dump($externalVariable, $secondExternalVariable); // returns two error notice, since the variables aren´t defined 

}

它无权访问任何外部变量。要为此命名空间授予此权限以访问外部变量,你需要通过闭包( use() ) 引入它。

$myFunction = function() use($externalVariable, $secondExternalVariable) {
   var_dump($externalVariable, $secondExternalVariable); // Hello Foo
}

这很大程度上归功于 PHP 的紧密变量范围 - 如果变量没有在范围内定义,或者没有带入 global 那么它就不存在了。

另请注意:

从父作用域继承变量与使用全局变量不同。全局变量存在于全局范围内,无论执行什么功能,它都是相同的。

闭包的父作用域是声明闭包的函数(不一定是从中调用它的函数)。

摘自匿名函数PHP 文档

在 PHP 中,闭包使用早期绑定方法。这意味着在定义闭包时,使用 use 关键字传递给闭包命名空间的变量将具有相同的值。

要更改此行为,你应该通过引用传递变量。

$rate = .05;

// Exports variable to closure's scope
$calculateTax = function ($value) use ($rate) {
    return $value * $rate;
};

$rate = .1; 

print $calculateTax(100); // 5
$rate = .05;

// Exports variable to closure's scope
$calculateTax = function ($value) use (&$rate) { // notice the & before $rate
    return $value * $rate;
};

$rate = .1;

print $calculateTax(100); // 10

使用/不使用闭包定义匿名函数时,不隐式需要默认参数。

$message = 'Im yelling at you';

$yell = function() use($message) {
    echo strtoupper($message);
};

$yell(); // returns: IM YELLING AT YOU