php匿名函数和闭包

匿名函数

在谈闭包之前,先说一下匿名函数,匿名函数实际上相当于把函数当做变量,不需要专门去定义一个函数。
在匿名函数出现之前,如果想把函数当做变量传递,得用字符串的形式,如下:

$anonymous = function (){ echo "hello ";};

function normal(){
    echo "world";
}
function testAnonymous($func){
    $func();
}

testAnonymous($anonymous);
testAnonymous('normal');

ps:另外php还提供了一个在运行时动态创建函数的方法,create_function

$newfunc = create_function('$a,$b', 'return "ln($a) + ln($b) = " . log($a * $b);');
echo "New anonymous function: $newfunc
";
echo $newfunc(2, M_E) . "
";
// outputs
// New anonymous function: lambda_1
// ln(2) + ln(2.718281828459) = 1.6931471805599

奇特的是这个create_function生成的函数居然是lambda_1类型,而不是Closure。

闭包

然而匿名函数中不能使用外部变量,为了解决这个问题,出现了闭包。
闭包可以捕获外部环境中的变量,由于在php中是早绑定,在闭包定义时,传入闭包的值就确定了。
如果外部变量发生了改变,那么闭包中的变量是不会变的,而且我们在闭包中也不能修改外部值。
解决办法是使用引用传值,在捕获的变量前添加&。

function test(){
    $v = "hello";
    $closure1 = function () use ($v){
        return $v;  
    };
    $closure2 = function () use (&$v){
        return $v;  
    };
    $v = "world";
    echo "closure1:".$closure1();
    echo "
";
    echo "closure2:".$closure2();
}

test();

另外如果在类中使用闭包,如过php版本低于5.3,是不能使用$this的。
闭包会编译成opcode并缓存起来,而create_function是在运行时动态创建,效率要比闭包低,建议使用闭包。

原文地址:https://www.cnblogs.com/xdao/p/php_anonymous_closure.html