Zamknięcie zdefiniowane w PHP może również zawierać modyfikator static
.Ustalenie, czy zamknięcie jest statyczne w PHP
$f = function() { };
$g = static function() { };
Statyczny zamknięcie nie może być związany przez Closure::bind
lub Closure::bindTo
i wyśle ostrzeżenie.
$g = Closure::bind(static function() { }, new stdClass());
// Warning: Cannot bind an instance to a static closure in ...
to również w przypadku zamknięcia utworzonych przez odbicie statyczne metody z 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 ...
Podczas denerwowania jest to dopuszczalne; jak jednak przeprowadzić test między zamknięciem statycznym a niestatycznym?
ReflectionMethod::isStatic
wydawało się, że potęga pracy, ale sensownie nie jak Closure::__invoke
jest instancja poziomu, a nie statyczne.
$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)
Ponadto sprawdzanie ReflectionMethod::getClosureThis
mogą ogólnie działać jako metody statycznej musi być ograniczeń, tym niemniej nie pokrywa zamknięcia poza określone metodą przykład, względnie narożny przypadku metod np które zostały niezwiązanego .
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
Tak, przekształcania, jaki sposób określić, czy zamknięcie jest statyczna (lub bardziej konkretnie, Bindable), czy nie?
Naprawdę wydaje się, że powinniśmy mieć ReflectionFunctionAbstract::isBindable
lub ReflectionMethod::isStatic
zostać przeniesiony do ReflectionFunctionAbstract
.
Ten fragment wygląda wyjątkowo znajomo ;-) – Dan
To jedyny sposób, jaki widziałem do tej pory. –
Podobnie. Nie podoba mi się to, że jest brudna z powodu '@ ', ale działa niezawodnie, i nie ma żadnych skrzynek narożnych, które mogę znaleźć. – Dan