Closure類為閉包類,PHP中閉包都是Closure的實例:
1 $func = function(){};
2 var_dump($func instanceof Closure);
輸出 bool(true)
Closure有兩個函數將閉包函數綁定到對象上去,
靜態方法Bind
public static Closure Closure::bind ( Closure $closure , object $newthis [, mixed $newscope = 'static' ] )
動態方法BindTo
public Closure Closure::bindTo ( object $newthis [, mixed $newscope = 'static' ] )
靜態閉包不能有綁定的對象($newthis 參數的值應該設為 NULL )
此時Closure不可以使用$this。
class Father
{
public $pu = "public variable";
public static $spu = 'public static';
}
class Son extends Father
{
}
class Other
{
}
$son = new Son();
$func = function(){
echo self::$spu;
};
($func -> bindTo(null, 'Son'))();
靜態閉包中不可以調用$this,否則會報錯。就像類的靜態方法不可以調用$this一樣
$son = new Son();
$func = function(){
echo $this -> $pu;
};
($func -> bindTo(null, 'Son'))();
報錯:
Fatal error: Uncaught Error: Using $this when not in object context in D:\laravel\test.php:21
Stack trace:
類作用域:
當閉包綁定到對象上時,或者綁定到null成為靜態對象,可以通過返回的閉包對象來調用對象的方法,同時可以設定第三個參數$newscope來設定對象中
屬性或方法對於閉包的訪問可見性。閉包的訪問可見性和$newscope類的成員函數是相同的。
class Father
{
protected $pu = "public variable";
protected static $spu = 'public static';
}
class Son extends Father
{
}
//Son中的方法可以正常訪問Father類中的protected屬性
class Other
{
}
//Other中的方法無法訪問Father類中的protected屬性
測試:
$son = new Son();
$func = function(){
echo $this -> pu;
};
(Closure::bind($func, $son, 'Son'))();
輸出 public variable
(Closure::bind($func, $son, 'Other'))();
報錯 Fatal error: Uncaught Error: Cannot access protected property Son::$pu
匿名函數都是Closure的實例所以可以調用 bindTo 方法。 bindTo方法 ($func -> bindTo($son, 'Son'))(); ($func -> bindTo($son, 'Other'))();
$newscope默認為‘Static'表示不改變,還是之前的作用域。
class Grand
{
protected $Grandvar = 'this is grand';
}
class Father extends Grand
{
protected $Fathervar = "this is Father";
}
class Mother extends Grand
{
protected $Mothervar = 'this is Mother';
}
class Son extends Father
{
protected $Sonvar = 'this is son';
}
$son = new Son();
$mon = new Mother();
$func = function(){
echo $this -> Grandvar;
};
綁定訪問作用域為'Son'的作用域,之后使用之前的默認作用域,
所以可以訪問Grandvar
$newFunc = Closure::bind($func, $son, 'Son');
$newFunc = Closure::bind($newFunc, $mon);
$newFunc();
未綁定訪問作用域,默認沒有權限
$newFunc = Closure::bind($func, $mon);
$newFunc();
http://php.net/manual/zh/class.closure.php
