6

我有一个正在传递闭包的函数。我想找出派生闭包的方法的名称。当我调用 print_r 时,它会输出:

Closure Object
(
  [static] => Array
    (
      [listener] => Event_Subscriber_Calq@vendor_product_created
      [container] => Illuminate\Foundation\Application Object
...

如何访问该侦听器值?我试过->static、::$static、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);

这太可怕了。还有另一种方法可以做到这一点吗?也许使用反射?

4

2 回答 2

7

我知道这篇文章很旧,但如果有人在寻找信息,你需要使用 ReflectionFunction:

$r = new ReflectionFunction($closure);
var_dump($r, $r->getStaticVariables(), $r->getParameters());

问候,亚历克斯

于 2017-12-08T11:18:54.953 回答
0

在最近的一个项目中,我决定使用包装类来使用声明性方法。该类允许设置描述回调来源的自由格式字符串,并且可以用作闭包的直接替换,因为它实现了该__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());
    }
}
于 2021-04-29T14:18:26.227 回答