关闭
闭包是一种无法访问外部作用域的匿名函数
在定义匿名函数时,你正在为该函数创建命名空间。它目前只能访问该命名空间。
$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 中,闭包使用早期绑定方法。这意味着在定义闭包时,使用 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