Закрытие, определенное в PHP, также может содержать модификатор static
.Определение, является ли замыкание статическим в PHP
$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
.
Этот фрагмент выглядит замечательно знакомым ;-) – Dan
Это единственный способ, который я видел до сих пор. –
Аналогичным образом. Мне не нравится, что он грязный из-за '@', но он работает надежно, и нет никаких угловых случаев, которые я могу найти. – Dan