PHP匿名函数和闭包使用的句法与普通函数相同,但匿名函和闭包数其实是伪装成函数的对象.
匿名函数:就是没有名称的函数.匿名函数可以赋值给变量,对象传递.不过匿名函数仍是函数,因此可以调用,还可以传入参数.匿名函数特别适合作为函数或方法的回调.
闭包:是指在创建时封装周围状态的函数.即使闭包所在的环境不存在了,闭包中封装的状态依然存在.
注意:理论上讲,闭包和匿名函数是不同的概念. 不过,PHP将其视作相同的概念.
一、匿名函数
匿名函数的语法:
$func = function(){
};//带结束符
示例demo:
$func = function ($param) {
echo($param);
};
$func('hello world');
二、闭包
2.1 将匿名函数放在普通函数中,也可以将匿名函数返回,这就构成了一个简单的闭包
function closureFunc1 () {
$func = function () {
echo "hello";
}; $func();
}
closureFunc1(); //输出: hello
2.2 在匿名函数中引用局部变量
function closureFunc2 () {
$num = 1;
$func = function () {
echo $num; }; $func();
}
closureFunc2(); //Notice: Undefined variable: num
上面的函数运行后,会报Notice错误,说明我们不能在匿名函数中这样使用局部变量,这时候就要引用一个php的关键字 use, 代码如下
function closureFunc2 () {
$num = 1;
$func = function () use($num) {
echo $num; }; $func();
}
closureFunc2(); //输出: 1
2.3 返回匿名函数
function closureFunc3(){
$num = 1; $func = function() use($num){
echo $num; }; return $func; }
$func = closureFunc3(); //函数返回匿名函数
$func(); //然后我们在用$func() 调用 //输出: 1
2.4 当我们在返回匿名函数时候怎么给匿名函数传参呢? 其实跟普通函数传参数一样
function closureFunc4(){
$num = 1; $func = function($str) use($num){
echo $num; echo "\n"; echo $str; };
return $func; }
$func = closureFunc4();
$func("hello, closure4"); //输出: //1 //hello, closure4
2.5 怎么用闭包来改变上下文引用的变量值?
function closureFunc5(){
$num = 1; $func = function() use($num) {
echo "\n"; $num++; echo $num; };
echo "\n";
echo $num;
return $func; }
$func = closureFunc5();
$func();
$func();
$func();
//输出:
// 1
// 2
// 2
// 2
看上面的输入结果,显然没有达到目的, 其实只要加一个 & 引用符号就可以了
function closureFunc5(){
$num = 2; $func = function() use(&$num) {
echo "\n";
$num++;
echo $num; };
echo "\n";
echo $num;
return $func; }
$func = closureFunc5();
$func();
$func();
$func();
//输出:
// 2
// 3
// 4
// 5
2.6 把匿名函数当作参数传递
function callFunc($func){
$func("argv"); } callFunc(function($str){
echo $str; })
//输出:
// argv
闭包就是能够读取其他函数内部变量的函数。
由于闭包会使得函数中的变量都被保存在内存中,内存消耗很大,所以不能滥用闭包,否则会造成网页的性能问题,在IE中可能导致内存泄露。解决方法是,在退出函数之前,将不使用的局部变量全部删除。
闭包会在父函数外部,改变父函数内部变量的值。所以,如果你把父函数当作对象(object)使用,把闭包当作它的公用方法(Public Method),把内部变量当作它的私有属性(private value),这时一定要小心,不要随便改变父函数内部变量的值。