php的闭包(Closure)匿名函数详解 php的闭包(Closure)也就是匿名函数,是PHP5.3引入的。 闭包的语法很简单,需要注意的关键字就只有use,use是连接闭包和外界变量。 复制代码 代码如下: $a = function() use($b) {} 简单例子如下: 复制代码 代码如下: function callback($fun) { $fun(); } $msg = "Hello, everyone"; $fun = function () use($msg) { print "This is a closure use string value, msg is: $msg.
/n"; }; $msg = "Hello, everybody"; callback($fun); 结果是:This is a closure use string value, msg is: Hello, everyone.
/n 在PHP新开放的闭包语法中, 我们用use来使用闭包外部定义的变量的。这里我们使用了外部变量$msg,定义完之后,又对其值进行了改变,闭包被执行后输出的是原始值。以传值方式传递的基础类型参数,闭包use的值在闭包创建是就确定了。 小应用如下: 复制代码 代码如下: /** * 一个利用闭包的计数器产生器 * 这里其实借鉴的是python中介绍闭包时的例子... * 我们可以这样考虑: * 1. counter函数每次调用, 创建一个局部变量$counter, 初始化为1. * 2. 然后创建一个闭包, 闭包产生了对局部变量$counter的引用. * 3. 函数counter返回创建的闭包, 并销毁局部变量, 但此时有闭包对$counter的引用, * 它并不会被回收, 因此, 我们可以这样理解, 被函数counter返回的闭包, 携带了一个游离态的 * 变量. * 4. 由于每次调用counter都会创建独立的$counter和闭包, 因此返回的闭包相互之间是独立的. * 5. 执行被返回的闭包, 对其携带的游离态变量自增并返回, 得到的就是一个计数器. * 结论: 此函数可以用来生成相互独立的计数器. */ function counter() { $counter = 1; return function() use(&$counter) {return $counter ++;}; } $counter1 = counter(); $counter2 = counter(); echo "counter1: " . $counter1() . "
/n"; echo "counter1: " . $counter1() . "
/n"; echo "counter1: " . $counter1() . "
/n"; echo "counter1: " . $counter1() . "
/n"; echo "counter2: " . $counter2() . "
/n"; echo "counter2: " . $counter2() . "
/n"; echo "counter2: " . $counter2() . "
/n"; echo "counter2: " . $counter2() . "
/n"; ?> 闭包的作用 1. 减少foreach的循环的代码 比如手册http://php.net/manual/en/functions.anonymous.php 中的例子Cart 复制代码 代码如下: products[$product] = $quantity; } public function getQuantity($product) { return isset($this->products[$product]) ? $this->products[$product] : FALSE; } public function getTotal($tax) { $total = 0.00; $callback = 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);; } } $my_cart = new Cart; // 往购物车里添加条目 $my_cart->add('butter', 1); $my_cart->add('milk', 3); $my_cart->add('eggs', 6); // 打出出总价格,其中有 5% 的销售税. print $my_cart->getTotal(0.05) . "\n"; // The result is 54.29 ?> 这里如果我们改造getTotal函数必然要使用到foreach。 2. 减少函数的参数 复制代码 代码如下: function html($code , $id="", $class=""){ if ($id !== "") $id = " id = \"$id\"" ; $class = ($class !== "")? " class =\"$class\">":">"; $open = "<$code$id$class"; $close = ""; return function ($inner = "") use ($open, $close){ return "$open$inner$close"; }; } 如果是使用平时的方法,我们会把inner放到html函数参数中,这样不管是代码阅读还是使用都不如使用闭包。 3. 解除递归函数 复制代码 代码如下: