查看 PHP 闭包的源代码

问题描述 投票:0回答:2

是否可以反映或以其他方式查看 PHP 闭包对象的源代码?也就是说,如果我做这样的事情

$closure = function()
{
    return 'Hi There';
};

然后是这样的

var_dump($closure);

PHP 输出

object(Closure)[14]

也就是说,我知道该对象是一个闭包,但我不知道它的作用。

我正在寻找一种反射方法、函数或调试扩展,以允许我转储匿名函数的实际主体。

php closures
2个回答
24
投票

从PHP中你能得到的东西是有限的,使用反射你只能得到函数的参数签名和源代码文件的起止行。我曾经写过一篇关于此的博客文章:http://www.metashock.de/2013/05/dump-source-code-of-closure-in-php/ ...

它引导我使用反射得到以下代码:

function closure_dump(Closure $c) {
    $str = 'function (';
    $r = new ReflectionFunction($c);
    $params = array();
    foreach($r->getParameters() as $p) {
        $s = '';
        if($p->isArray()) {
            $s .= 'array ';
        } else if($p->getClass()) {
            $s .= $p->getClass()->name . ' ';
        }
        if($p->isPassedByReference()){
            $s .= '&';
        }
        $s .= '$' . $p->name;
        if($p->isOptional()) {
            $s .= ' = ' . var_export($p->getDefaultValue(), TRUE);
        }
        $params []= $s;
    }
    $str .= implode(', ', $params);
    $str .= '){' . PHP_EOL;
    $lines = file($r->getFileName());
    for($l = $r->getStartLine(); $l < $r->getEndLine(); $l++) {
        $str .= $lines[$l];
    }
    return $str;
}

如果您有以下关闭:

$f = function (Closure $a, &$b = -1, array $c = array())
  use ($foo) 
{
    echo $this->name;
    echo 'test';
};

closure_dump()
将给出以下结果:

function (Closure $a, &$b = -1, array $c = array (
)){
 use ($foo)
{
    echo $this->name;
    echo 'test';
};

你会看到它是不完美的(数组参数)。此外,它也无法正确处理某些边缘情况,特别是当闭包嵌套或多个内联闭包将传递给一行中的函数时。后者对我来说似乎是最有问题的。由于您只能从反射中获得起始行和结束行,因此在这种情况下,两个函数都将位于该行上,并且您没有有用的信息来决定应转储其中哪一个。到目前为止,我还没有找到解决方案,我也不确定是否有解决方案。

但是,在大多数情况下,只要您不依赖它,它至少应该对调试有帮助。 随意增强它!


0
投票

查看https://github.com/yiisoft/var-dumper,它支持任何(箭头、传统)闭包。

© www.soinside.com 2019 - 2024. All rights reserved.