深入理解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
?>
//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
?>
相关文章推荐
- 深入理解PHP中的匿名函数
- [李景山php] 深入理解PHP内核[读书笔记]--第四章:函数的实现 --匿名函数及闭包
- PHP中的匿名函数的深入理解
- 深入理解PHP中的匿名函数
- 深入理解 PHP 匿名函数关键字 use 的 Runtime Context
- [转]深入理解JavaScript闭包(closure)
- 深入理解JavaScript闭包(closure)
- 深入理解Javascript闭包(closure)
- 深入理解Javascript闭包(closure)
- 深入理解PHP原理之变量作用域(Scope in PHP)
- 深入理解PHP之执行周期
- 深入理解PHP原理之扩展载入过程
- 深入理解PHP原理之Opcodes
- 深入理解JavaScript闭包(closure)
- 深入理解PHP之数组(遍历顺序)
- [转]深入理解JavaScript闭包(closure)
- 深入理解Javascript闭包(closure)
- 深入理解Javascript闭包(closure)
- 深入理解PHP原理之Opcodes
- 深入理解JavaScript闭包(closure)