Чтение аргументов "это" и "использовать" из закрытия PHP
При создании метода, возвращающего замыкание в PHP:
class ExampleClass {
public function test() {
$example = 10;
return function() use ($example) {
return $example;
};
}
}
Результат print_r
содержит this
(класс, метод которого создал замыкание) и static
, которые, по-видимому, являются значениями, связанными в операторе use ()
замыкания:
$instance = new ExampleClass();
$closure = $instance->test();
print_r($closure);
Производство:
Closure Object (
[static] => Array (
[example] => 10
)
[this] => ExampleClass Object()
)
Однако я ни за что на свете не смогу понять, как уловить эти ценности. Невозможно использовать любую форму доступа к свойствам (например, $closure->static
или $closure->{'static'}
) без получения следующее:
Неустранимая ошибка PHP: Неперехваченная ошибка: Объект закрытия не может иметь свойств в XYZ.
Нотация доступа к массиву, очевидно, также не работает:
Неустранимая ошибка PHP: Неперехваченная ошибка: Невозможно использовать объект типа Closure в качестве массива в XYZ.
JSON, кодирующий объект, помимо того, что делает значения бесполезными, если бы они были объектами, предоставляет пустой объект JSON {}
, а использование класса ReflectionFunction
не обеспечивает доступ к этим предметы.
Документация по закрытию также не предоставляет никаких средств доступа к этим значениям.
Помимо выполнения чего-то постыдного, такого как буферизация вывода и синтаксический анализ print_r
или подобного, я на самом деле не вижу способа получить эти значения.
Я упускаю что-то очевидное?
Примечание: Вариант использования предназначен для реализации запоминания, и эти значения были бы чрезвычайно полезны для определения того, является ли вызов соответствует предыдущему кэшированному вызову.
1 answers
Похоже, вы, возможно, упустили из виду некоторые методы ReflectionFunction
.
Взгляните на ReflectionFunction::getClosureThis()
метод. Я отследил это, просмотрев исходный код PHP 7, выполнив поиск zend_get_closure_this_ptr()
который определяется в zend_closures.c
.
В руководстве в настоящее время не так много документации для этой функции. Я использую 7.0.9; попробуйте запустить этот код на основе вашего примера:
class ExampleClass {
private $testProperty = 33;
public function test() {
$example = 10;
return function() use ($example) {
return $example;
};
}
}
$instance = new ExampleClass();
$closure = $instance->test();
print_r($closure);
$func = new ReflectionFunction($closure);
print_r($func->getClosureThis());
Вы должны получить результат, аналогичный к
Closure Object
(
[static] => Array
(
[example] => 10
)
[this] => ExampleClass Object
(
[testProperty:ExampleClass:private] => 33
)
)
ExampleClass Object
(
[testProperty:ExampleClass:private] => 33
)
Что касается статических переменных закрытия, они возвращаются с ReflectionFunction::getStaticVariables()
:
php > var_dump($func->getStaticVariables());
array(1) {
["example"]=>
int(10)
}