Как проверить закрытие в 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());
    }
}
Другие вопросы по тегам