这让我在学习闭包是什么以及如何使用它们时感到困惑,但在 PHP 中被称为闭包的东西与其他语言(如 JavaScript)中被称为闭包的东西不同。
在 JavaScript 中,闭包可以被认为是一个作用域,当您定义一个函数时,它会隐式地继承它定义的作用域,这被称为它的闭包,并且无论它在哪里使用,它都会保留该作用域。多个函数可以共享同一个闭包,只要它们在它们可访问的作用域内,它们就可以访问多个闭包。
在 PHP 中,闭包是一个可调用类,您已手动绑定了参数。
这是一个细微的差别,但我认为值得一提。
(PHP 5 >= 5.3.0, PHP 7, PHP 8)
用于表示 匿名函数 的类。
匿名函数生成此类型的对象。此类具有允许在创建匿名函数后进一步控制匿名函数的方法。
除了这里列出的方法之外,此类还有一个 __invoke
方法。这是为了与实现 调用魔术 的其他类保持一致,因为此方法不用于调用函数。
这让我在学习闭包是什么以及如何使用它们时感到困惑,但在 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)
?>