Можно ли сбросить выражение параметра в PHP?

#php

#php

Вопрос:

Для сценариев тестирования PHP мне нужна функция report() , которая будет сообщать результаты некоторых выражений, например:

 report(in_array(null, $array));
report(in_array(false, $array)); 
# etc...
  

Вывод должен выглядеть так:

 in_array(null, $array) => false
in_array(false, $array) => true
  

Итак, я хочу распечатать выражение вместе с результатом. Таким образом, в функции отчета мне нужны некоторые средства, как напечатать выражение, которое было задано вызывающим:

 function report($expr)
{
    SOME_FUNCTION($expr) 
        # function I'm looking for!!
        # function which would write the string 'in_array(null, $array)' to output!
    echo " => ";
    echo $expr;
    echo "<br>";
}
  

Существует ли какая-либо такая функция, которая сбрасывала бы выражение, заданное вызывающим?
Я знаю, что это не может быть «нормальной» функцией, это должно быть как-то связано с внутренними компонентами PHP. Но если есть волшебные вещи, такие как debug_print_backtrace() , __FUNCTION__ или __LINE__ , тогда я думаю, что все еще может быть какой-то шанс…

Комментарии:

1. Это похоже на то, что assert('$expr()'); делает. Хотя вы, возможно, не сможете использовать его для своего дела.

Ответ №1:

Напрямую, нет, нет чистого метода, чтобы делать то, что вы хотите.

С учетом сказанного, вы могли бы использовать debug_backtrace для получения стека. Затем все, что вам нужно сделать, это вернуться к стеку на единицу (перейти ко 2-му элементу массива), и у вас есть информация о файле и строке. Затем вам нужно будет проанализировать эту строку, чтобы извлечь имя функции и входные данные.

Это не было бы чистым. Вероятно, это будет нелегко. И это не было бы надежным на 100%. Но это должно работать в большинстве случаев…

вот простой пример служебной функции для этого. Просто вызовите его с именем функции, и он выдаст вам буквальный вызывающий объект функции:

 function getArgs($func) {
    $d = debug_backtrace();
    $call = $d[1];
    $file = file($call['file']);
    $line = $file[$call['line'] - 1];
    if (preg_match('(' . preg_quote($func, '(') . '((.*));)', $line, $match)) {
        return $match[1];
    }
    return $line;
}
  

И вот пример:

 function doSomething($arg) {
    $call = getArgs(__FUNCTION__);
    echo $call . ' - ' . $arg;
}

doSomething(strlen('foo'));
  

Выводил бы:

strlen(‘foo’) — 3

Комментарии:

1. @TomasT: это не на 100% надежно (особенно синтаксический анализ вызовов), но это лучше, чем ничего. Он попытается вернуть параметр, и если это не удастся, он вернет всю строку. Вы также могли бы немного расширить регулярное выражение…