我正在检查一些 PHP 5.3.0
功能,并在网站上遇到一些看起来很有趣的代码:
public function getTotal($tax)
{
$total = 0.00;
$callback =
/* This line here: */
function ($quantity, $product) use ($tax, &$total)
{
$pricePerItem = constant(__CLASS__ . "::PRICE_" .
strtoupper($product));
$total += ($pricePerItem * $quantity) * ($tax + 1.0);
};
array_walk($this->products, $callback);
return round($total, 2);
}
作为anonymous functions的一个例子 .
有人知道吗?有文件吗?如果它被使用它看起来很邪恶?
5 回答
这就是PHP表达closure的方式 . 这根本不是邪恶的,事实上它非常强大和有用 .
基本上这意味着你允许匿名函数在其范围之外的"capture"局部变量(在这种情况下,
$tax
和对$total
的引用)并保留它们的值(或者在$total
对$total
本身的引用的情况下)为匿名函数本身内的状态 .一个更简单的答案 .
function ($quantity) use ($tax, &$total) { .. };
闭包是一个赋给变量的函数,所以你可以传递它
闭包是一个单独的命名空间,通常,您无法访问在此命名空间外定义的变量 . 有 use 关键字:
use 允许您访问(使用)闭包内的后续变量 .
use 是早期绑定 . 这意味着在定义闭包时变量值是COPIED . 因此,在闭包内部修改
$tax
没有外部效果,除非它是一个指针,就像对象一样 .您可以将变量作为指针传递,就像
&$total
一样 . 这样,修改$total
的值有外部效果,原始变量的值会发生变化 .闭包内定义的变量也无法从闭包外部访问 .
闭包和功能具有相同的速度 . 是的,您可以在脚本上使用它们 .
至于@Mytskine pointed out可能是最好的深入解释是RFC for closures . (为此赞成他 . )
闭合很漂亮!他们解决了许多匿名函数带来的问题,并且可以使代码变得非常优雅(至少只要我们谈论php) .
javascript程序员一直使用闭包,有时甚至不知道它,因为绑定变量没有明确定义 - 这就是php中的“use” .
有比上面更好的现实世界的例子 . 假设您必须按子值对多维数组进行排序,但键会更改 .
警告:未经测试的代码(我没有安装php5.3 atm),但它看起来应该是这样的 .
有一个缺点:如果你用闭包来对付它们,很多php开发者可能会有点无助 .
为了更好地理解闭包的好处,我会给你另一个例子 - 这次是在javascript中 . 其中一个问题是范围和浏览器固有的异步性 . 特别是,如果涉及
window.setTimeout();
(或-interval) . 所以,你将一个函数传递给setTimeout,但你不能真正给出任何参数,因为提供参数会执行代码!myFunction返回一个带有一种预定义参数的函数!
说实话,自从5.3和匿名函数/闭包以来我更喜欢php . 命名空间可能更重要,但它们的性感要差得多 .
function () use () {}
是PHP的闭包,你必须使用use
来包含父function
的变量 .Zupa用“使用”解释闭包以及EarlyBinding和引用“使用”变量之间的区别做得很好 .
所以我用一个变量的早期绑定(=复制)做了一个代码示例:
引用变量的示例(注意变量前的'&'字符);