匿名函數(shù)可用于動態(tài)創(chuàng)建函數(shù),并保存到一個變量中刀闷。舉個栗子:
$func = function(){
exit('Hello world!!');
};//這里必須要有;結(jié)尾
$func();
等效于:
function func(){
exit('Hello world!!');
}
func();
看上去沒什么新奇的地方,別急仰迁,繼續(xù)看甸昏。
function operate($operator){
if($operator == "-"){
return function($a,$b){
return $a-$b;
};
}else{
return function($a,$b){
return $a+$b;
};
}
}
$subtraction = operate("-");
echo $subtraction(4,3);//1
$addition = operate("+");
echo $addition(1,2);//3
通過operate函數(shù),我們可以生成不同的函數(shù)作為結(jié)果返回徐许,并將這個結(jié)果直接作為函數(shù)調(diào)用施蜜,上面的代碼分別動態(tài)創(chuàng)建了減法運算和加法運算函數(shù)。
展示一個實戰(zhàn)中用到的技巧:
<?php
header("Content-Type:text/html;charset=utf-8");
class Di{
private $_factory;
public function set($id,$value){
$this->_factory[$id] = $value;
}
public function get($id){
$value = $this->_factory[$id];
return $value();
}
}
class User{
private $_username;
function __construct($username="") {
$this->_username = $username;
}
function getUserName(){
return $this->_username;
}
}
//從這里開始看
$di = new Di();
$di->set("zhangsan",function(){
return new User('張三');
});
$di->set("lisi",function(){
return new User("李四");
});
echo $di->get("zhangsan")->getUserName();
echo $di->get("lisi")->getUserName();
代碼中有一個Di容器用來保存對象實例雌隅,然后通過set()方法注冊服務(wù)翻默,通過get()方法獲取服務(wù)。
我們看到$di->set()的時候恰起,使用了匿名函數(shù)修械,我們預(yù)先注冊了zhangsan和lisi兩個服務(wù),這兩個服務(wù)都是User類的實例检盼,在$di->set的時候?qū)嶋H上并沒有實例化祠肥,而是在$di->get()的時候才執(zhí)行了匿名函數(shù)并將對象返回,這就實現(xiàn)了按需實例化,不用則不實例化仇箱,提高效率。
閉包特性:
經(jīng)常寫js的同學(xué)應(yīng)該知道js的閉包特性东羹,簡單的說就是在一個函數(shù)里可以定義子函數(shù)剂桥,父函數(shù)中的變量在子函數(shù)中可以直接使用,那么PHP的閉包怎么用呢属提?有一點區(qū)別权逗。
function func1($a){
return function() use ($a){
echo $a;
};
}
$a = func1("a");
$a();//輸出a
當(dāng)你想將外層變量傳進內(nèi)層匿名函數(shù)時,使用use (變量)的方式冤议。
閉包的用途可以用于很多地方斟薇,常見于DI模式中。