而在PHP 5.3发布的时候, 其中有一条new feature就是支持闭包/Lambda Function, 我第一反应是以为zval新增了一个IS_FUNCTION, 但实际上是构造了一个PHP 5.3引入的Closure”类”的实例, Closure类的构造函数是私有的, 所以不能被直接实例化, 另外Closure类是Final类, 所以也不能做为基类派生子类.
- //php-5.3.0
- $class = new ReflectionClass("Closure");
- var_dump($class->isInternal());
- var_dump($class->isAbstract() );
- var_dump($class->isFinal());
- var_dump($class->isInterface());
- //输出:
- bool(true)
- bool(false)
- bool(true)
- bool(false)
- ?>
而PHP 5.3中对闭包的支持, 也仅仅是把要保持的外部变量, 做为Closure对象的”Static属性”(并不是普通意义上的可遍历/访问的属性).
- //php-5.3.0
- $b = "laruence";
- $func = function($a) use($b) {};
- var_dump($func);
- /* 输出:
- object(Closure)#1 (2) {
- ["static"]=>
- array(1) {
- ["b"]=> string(8) "laruence"
- }
- ["parameter"]=>
- array(1) {
- ["$a"]=> string(10) "<required>"
- }
- }
- */
闭包函数也可以作为变量的值来使用。PHP 会自动把此种表达式转换成内置类 的对象实例。把一个 closure 对象赋值给一个变量的方式与普通变量赋值的语法是一样的,最后也要加上分号:
<?php
$greet = function($name){ printf("Hello %s\r\n", $name);};$greet('World');$greet('PHP');?>仔细看下面的例子...看看作用域的不同
<?php$result = 0;$one = function(){ var_dump($result); };$two = function() use ($result){ var_dump($result); };$three = function() use (&$result){ var_dump($result); };$result++;$one(); // outputs NULL: $result is not in scope$two(); // outputs int(0): $result was copied$three(); // outputs int(1)?>
<?php//set up variable in advance$myInstance = null;$broken = function() uses ($myInstance){ if(!empty($myInstance)) $myInstance->doSomething();};$working = function() uses (&$myInstance){ if(!empty($myInstance)) $myInstance->doSomething();}//$myInstance might be instantiated, might not beif(SomeBusinessLogic::worked() == true){ $myInstance = new myClass();}$broken(); // will never do anything: $myInstance will ALWAYS be null inside this closure.$working(); // will call doSomething if $myInstance is instantiated?>