今天遇到的個問題,php
<?php class A { public static function testClosureScope() { $objB = (new B)->setAttr1( function (){ self::otherFunc();//todo 此處須要使用當前實例化的B對象做爲參數 } ); } public static function otherFunc(B $objB) { var_dump($objB); } } class B { public $attr1; /** * @return mixed */ public function getAttr1() { return $this->attr1; } /** * @param mixed $attr1 */ public function setAttr1($attr1) { $this->attr1 = $attr1; return $this; } }
問題所在 :上面todo 的地方須要完善,How?閉包
1.傳遞 $this函數
<?php class A { public static function testClosureScope() { $objB = (new B)->setAttr1( function (){ self::otherFunc($this);//todo 此處須要使用當前實例化的B對象做爲參數 } ); } public static function otherFunc(B $objB) { var_dump($objB); } }
ERROR, 想法是好的,可是這個$this,是傳遞不過去的,緣由:this
當前 testClosureScope 方法是staticcode
即便所在方法不是static,$this 也會自動綁定到 Class A的實例,即 Closure中 的 $this會自動bind到定義的類,不必定是調用的類對象
#################################################################################################繼承
解決法遞歸
1.Closure的繼承做用域變量作用域
<?php class A { public static function testClosureScope() { $objB = (new B); $objB->setAttr1( function ()use($objB){ self::otherFunc($objB);//todo 此處須要使用當前實例化的B對象做爲參數 } ); return $objB; } public static function otherFunc(B $objB) { var_dump($objB); } } class B { public $attr1; /** * @return mixed */ public function getAttr1() { return $this->attr1; } /** * @param mixed $attr1 */ public function setAttr1($attr1) { $this->attr1 = $attr1; return $this; } } $obj = A::testClosureScope(); $cf = $obj->getAttr1(); $cf();//RECURSION 遞歸引用本身
2. Closure 的 bindToget
<?php class A { public static function testClosureScope() { $f = function (){ self::otherFunc($this);//此處須要使用當前實例化的B對象做爲參數 }; $objB = (new B); $bindF = $f->bindTo($objB);//閉包綁定至 B實例;因此上面的 $this 纔會生效;注意必定要接收返回值 $objB->setAttr1($bindF); return $objB; } public static function otherFunc(B $objB) { var_dump($objB); } } class B { public $attr1; /** * @return mixed */ public function getAttr1() { return $this->attr1; } /** * @param mixed $attr1 */ public function setAttr1($attr1) { $this->attr1 = $attr1; return $this; } } $obj = A::testClosureScope(); $cf = $obj->getAttr1(); $cf();