【发布时间】:2015-03-18 19:36:12
【问题描述】:
PHP 中定义的闭包也可以带有static 修饰符。
$f = function () { };
$g = static function () { };
静态闭包不能通过Closure::bind或Closure::bindTo绑定,会发出警告。
$g = Closure::bind(static function () { }, new stdClass());
// Warning: Cannot bind an instance to a static closure in ...
这也是通过使用ReflectionMethod::getClosure 反射静态方法创建的闭包的情况。
class MyClass
{
public static function myStaticMethod() { }
}
// reflect MyClass::myStaticMethod, create an unbound closure, and try to bind it
$f = (new ReflectionMethod(MyClass::class, 'myStaticMethod'))
->getClosure()
->bindTo(new stdClass());
// Warning: Cannot bind an instance to a static closure in ...
虽然烦人,但这是可以接受的; 但是,如何在静态闭包和非静态闭包之间进行测试?
ReflectionMethod::isStatic 看起来它可能可以工作,但显然不是因为Closure::__invoke 是实例级的,而不是静态的。
$f = static function () { };
// reflect Closure::__invoke because I think I'm tricky
$r = new ReflectionMethod($f, '__invoke');
// and it's not static anyway
var_dump($r->isStatic()); // bool(false)
此外,检查ReflectionMethod::getClosureThis 通常可以工作,因为静态方法必须是未绑定的,但这不包括在实例方法之外定义的闭包,或已未绑定。
class MyClass
{
public function myInstanceMethod() { }
}
$o = new MyClass();
// reflect MyClass::myInstanceMethod, create a bound closure, and then unbind it
$f = (new ReflectionMethod($o, 'myInstanceMethod'))
->getClosure($o)
->bindTo(null);
// then reflect the closure
$r = new ReflectionFunction($f);
// and see it's bound to nothing, as would be the case of a static closure
var_dump($r->getClosureThis()); // NULL
所以,重申一下,您如何确定闭包是否是静态的( 或者更具体地说,是可绑定的)?
看起来我们真的应该有一个ReflectionFunctionAbstract::isBindable,或者ReflectionMethod::isStatic 被移动到ReflectionFunctionAbstract。
【问题讨论】:
标签: php scope closures static-methods