標籤:http io os 使用 ar sp cti log on
而在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 匿名函數和 Closure