您的位置:首页 > 编程语言 > PHP开发

深入理解php 匿名函数和 Closure

2014-09-18 19:59 288 查看
而在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 的对象实例。把一个 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 be
if(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

?>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: