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
。
3条答案
按热度按时间jum4pzuy1#
如果绑定有效,闭包将绑定一个$this,所以,只要绑定它,然后检查$this,如果它为null,那么它是一个静态闭包。
qoefvg9y2#
现在看来不可能了。
你可以在这里找到一些争论:https://bugs.php.net/bug.php?id=64761
我现在唯一真实的为自己使用的解决方法是手动添加
->isBindable
属性。这是我在这里找到的一些代码https://github.com/atoum/atoum/blob/master/classes/test/adapter/invoker.php
也许会给予你一些启发
py49o6xq3#
很老的问题,但仍然出现在谷歌搜索。提到的
isStatic
现在存在于ReflectionFunction
中,截至php 8. 1(我测试了它)截至编写时,文档中未显示此信息。请参见:https://www.php.net/manual/en/class.reflectionfunction.php
我还在这里创建了一个丢失文档报告:https://github.com/php/doc-en/issues/2136