關閉

閉包是一種無法訪問外部作用域的匿名函式

在定義匿名函式時,你正在為該函式建立名稱空間。它目前只能訪問該名稱空間。

$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