這在我還在學習閉包是什麼以及如何使用它們時讓我有些困惑,但 PHP 中所稱的閉包與其他語言(例如 JavaScript)中所稱的閉包並不相同。
在 JavaScript 中,閉包可以被認為是一個作用域,當您定義一個函式時,它會默默地繼承它被定義的作用域,這稱為它的閉包,並且無論它在哪裡使用都會保留它。多個函式可以共享同一個閉包,並且只要它們在其可訪問的作用域內,它們就可以訪問多個閉包。
在 PHP 中,閉包是一個可呼叫的類別,您已手動將參數綁定到該類別。
這是一個細微的區別,但我覺得值得一提。
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
這在我還在學習閉包是什麼以及如何使用它們時讓我有些困惑,但 PHP 中所稱的閉包與其他語言(例如 JavaScript)中所稱的閉包並不相同。
在 JavaScript 中,閉包可以被認為是一個作用域,當您定義一個函式時,它會默默地繼承它被定義的作用域,這稱為它的閉包,並且無論它在哪裡使用都會保留它。多個函式可以共享同一個閉包,並且只要它們在其可訪問的作用域內,它們就可以訪問多個閉包。
在 PHP 中,閉包是一個可呼叫的類別,您已手動將參數綁定到該類別。
這是一個細微的區別,但我覺得值得一提。
小技巧:您可以透過參考在自身內部使用閉包。
刪除目錄及其所有子目錄和檔案的範例
<?php
$deleteDirectory = null;
$deleteDirectory = function($path) use (&$deleteDirectory) {
$resource = opendir($path);
while (($item = readdir($resource)) !== false) {
if ($item !== "." && $item !== "..") {
if (is_dir($path . "/" . $item)) {
$deleteDirectory($path . "/" . $item);
} else {
unlink($path . "/" . $item);
}
}
}
closedir($resource);
rmdir($path);
};
$deleteDirectory("path/to/directoy");
?>
作用域
閉包會封裝其作用域,這表示它無法存取定義或執行它的作用域。 然而,可以使用 `use` 關鍵字將變數從父作用域(定義閉包的位置)繼承到閉包中。
function createGreeter($who) {
return function() use ($who) {
echo "Hello $who";
};
}
$greeter = createGreeter("World");
$greeter(); // Hello World
這會以值的方式繼承變數,也就是在閉包內部使用其原始名稱建立副本。
來源:Zend 認證學習指南。
比較閉包
<?php
(string) new ReflectionFunction($fn) === (string) new ReflectionFunction($fn2)
?>