今天遇到的个问题,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();