2014-08-30 3 views
7

Возможно ли отразить или иначе просмотреть источник объекта закрытия PHP? То есть, если я что-то вроде этогоПросмотр источника закрытия PHP

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

, а затем что-то вроде этого

var_dump($closure); 

PHP выходы

object(Closure)[14] 

То есть, я знаю, что объект это закрытие, но у меня есть не знаю, что он делает.

Я ищу метод отражения, функцию или отладочное расширение, которое позволит мне сбросить фактическое тело анонимной функции.

ответ

10

Что вы можете получить от 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'; 
}; 

Вы видите это несовершенный (параметр массива). Кроме того, он не будет обрабатывать некоторые случаи краев должным образом, особенно если замыкания вложены или несколько встроенных замыканий будут переданы функции в одну строку. Последний выглядит для меня наиболее проблематичным. Поскольку вы получаете только начальную и конечную линии от отражения, обе функции будут на этой линии в этом случае, и у вас нет никакой полезной информации, чтобы решить, какой из них должен быть сброшен. До сих пор я не нашел для этого решения, также я не уверен, есть ли решение.

Однако в большинстве случаев он должен по крайней мере быть полезным для отладки, если вы не полагаетесь на него. Feel free to enhance it!

+0

Как я могу оценить приведенный код после изменения, не используя eval()? – Omranic

+0

Что вы имеете в виду * после модификации *? – hek2mgl

+0

Я знаю, что это старо, но это все еще для меня .. Ну, после модификации означает, что я взял отраженный код закрытия, удалил несколько строк и добавил других, и поскольку теперь это просто строка, мне нужно оценить приведенный измененный код без использования eval() – Omranic

Смежные вопросы