Как проверить закрытие в php?
У меня есть функция, которая проходит Закрытие. Я хочу узнать название метода, по которому происходит замыкание. Когда я вызываю print_r, он выводит это:
Closure Object
(
[static] => Array
(
[listener] => Event_Subscriber_Calq@vendor_product_created
[container] => Illuminate\Foundation\Application Object
...
Как мне оценить значение этого слушателя? Я попытался -> статические,::$ статические, getStatic(), я не могу придумать способ получить значение.
В настоящее время я планирую использовать буферизацию вывода для захвата вывода из var_dump. Я не могу использовать print_r для этого, потому что замыкание содержит ссылку и объект, который ссылается на себя, а print_r требует много времени для обработки рекурсии. Я также не могу использовать var_export, потому что он не включает значение, которое я хочу в выводе. Итак, это мое решение:
ob_start();
var_dump($closure);
$data = ob_get_clean();
$data = preg_replace('#^([^\n]*\n){4}#', '', $data);
$data = preg_replace('#\n.*#', '', $data);
$data = preg_replace('#.*string.[0-9]+. "(.*)".*#', '\1', $data);
list($class, $method) = explode('@', $data);
Что ужасно Есть ли другой способ сделать это? Может быть, с помощью отражения?
2 ответа
Я знаю, что этот пост старый, но в случае, если кто-то ищет информацию, вам нужно использовать ReflectionFunction:
$ r = новая функция ReflectionFunction($closure); var_dump($r, $r->getStaticVariables(), $r->getParameters());
С уважением, Алекс
В недавнем проекте я выбрал декларативный подход с использованием класса-оболочки. Класс позволяет установить строку произвольной формы, описывающую источник обратного вызова, и может использоваться как прямая замена закрытия, поскольку он реализует
__invoke()
метод.
Пример:
use ClosureTools;
$closure = new NamedClosure(
function() {
// do something
},
'Descriptive text of the closure'
);
// Call the closure
$closure();
Чтобы получить доступ к информации о закрытии:
if($closure instanceof NamedClosure) {
$origin = $closure->getOrigin();
}
Поскольку начало координат является строкой произвольной формы, для него может быть установлено любое значение, полезное для идентификации замыкания, в зависимости от варианта использования.
Вот скелет класса:
<?php
declare(strict_types=1);
namespace ClosureTools;
use Closure;
class NamedClosure
{
/**
* @var Closure
*/
private $closure;
/**
* @var string
*/
private $origin;
/**
* @param Closure $closure
* @param string $origin
*/
public function __construct(Closure $closure, string $origin)
{
$this->closure = $closure;
$this->origin = $origin;
}
/**
* @return string
*/
public function getOrigin() : string
{
return $this->origin;
}
public function __invoke()
{
return call_user_func($this->closure, func_get_args());
}
}