Посмотрим правде в глаза, debug_backtrace()
не очень debug_backtrace()
. Кто-нибудь закодировал обертку?
И каков ваш любимый красивый var_dump()
(который можно использовать в коммерческих проектах, поэтому нет GPL (хотя LGPL в порядке))
См. Также: Более симпатичная / информативная альтернатива Var_dump в PHP?
Шесть лет – и десять тысяч просмотров этого вопроса – позже, и я все еще использую это. Это не очень хорошо выглядит на экране, как Kint (что отлично).
Это простой текст, который я могу написать себе в автоматические отчеты об ошибках и может отображаться в консоли разработчика браузера с помощью ChromePhp .
/** * @brief Returns an HTML formatted string showing details of the backtrace * * Example: * * F:\Dropbox\programs\Xampp\htdocs\api\q.php:48 e(373, 'beer', 'curry') * F:\Dropbox\programs\Xampp\htdocs\api\q.php:53 d(26366, 28255, 8364) * F:\Dropbox\programs\Xampp\htdocs\api\q.php:58 c() * F:\Dropbox\programs\Xampp\htdocs\api\q.php:63 b(1283, 15488, 29369) * F:\Dropbox\programs\Xampp\htdocs\api\q.php:72 a(788, 6077, 25010) */ function FormatBacktrace() { $result = '<h4>Backtrace</h4>'; foreach (debug_backtrace() as $trace) { if ($trace['function'] ==__FUNCTION__) continue; $parameters = ''; foreach ($trace['args'] as $parameter) $parameters .= $parameter . ', '; if (substr($parameters, -2) == ', ') $parameters = substr($parameters, 0, -2); if (array_key_exists('class', $trace)) $result .= sprintf("%s:%s %s::%s(%s)<br>", $trace['file'], $trace['line'], $trace['class'], $trace['function'], $parameters); else $result .= sprintf("%s:%s %s(%s)<br>", $trace['file'], $trace['line'], $trace['function'], $parameters); } return $result; }
Расширение Xdebug может печатать стоп-кадры с настраиваемой степенью многословия.
Он также предлагает некоторые дополнительные функции var_dump (), такие как синтаксическая раскраска:
Редактировать:
Что касается включения Xdebug в коммерческий проект.
Лицензия Xdebug имеет всего несколько терминов и кажется довольно разрешительной.
Xdebug является расширением C. Поскольку такое перераспределение его или его части в вашем проекте может быть несколько сложным. В зависимости от ваших требований я вижу несколько вариантов:
У вас также есть kint
( github repo ), у которого есть пакет composer
в репозитории packagist
Поэтому либо загружайте библиотеку вручную, либо composer
, это просто вопрос:
$ composer init $ composer require raveren/kint $ composer install
Затем вместо ini_set('display_errors', 'On');
, Я предпочитаю использовать этот простой обработчик в моем основном (первом) файле include:
if ( getenv('__project_env__') === 'DEV') { error_reporting(E_ALL | E_STRICT); function shutdown_handler() { $error = error_get_last(); Kint::trace(); Kint::dump($error); } register_shutdown_function('shutdown_handler'); } else { ... }
С __project_env__
устанавливается в Apache Virtualhost ( SetEnv __project_env__ "DEV"
), чтобы не загрязнять разные ветви репозитория git
где проект живет с элементами конфигурации, которые по сути являются environmental
Вот скриншот о том, как выглядит трассировка (каждый шаг сворачивается):
Вот моя симпатичная оболочка для печати, предназначенная для вывода без браузера, то есть журналов ошибок или консоли:
function stackTrace() { $stack = debug_backtrace(); $output = ''; $stackLen = count($stack); for ($i = 1; $i < $stackLen; $i++) { $entry = $stack[$i]; $func = $entry['function'] . '('; $argsLen = count($entry['args']); for ($j = 0; $j < $argsLen; $j++) { $func .= $entry['args'][$j]; if ($j < $argsLen - 1) $func .= ', '; } $func .= ')'; $output .= $entry['file'] . ':' . $entry['line'] . ' - ' . $func . PHP_EOL; } return $output; }
Превосходный метод stackTrace от jhurliman – это действительно здорово. Но для меня это создавало множество PHP-предупреждений, которые также загромождали журнал. Я добавил немного больше ошибок и проверки типов, что приводит к очень хорошей трассировке стека в журналах. Вот модифицированная версия кода jhurliman:
function stackTrace() { $stack = debug_backtrace(); $output = ''; $stackLen = count($stack); for ($i = 1; $i < $stackLen; $i++) { $entry = $stack[$i]; $func = $entry['function'] . '('; $argsLen = count($entry['args']); for ($j = 0; $j < $argsLen; $j++) { $my_entry = $entry['args'][$j]; if (is_string($my_entry)) { $func .= $my_entry; } if ($j < $argsLen - 1) $func .= ', '; } $func .= ')'; $entry_file = 'NO_FILE'; if (array_key_exists('file', $entry)) { $entry_file = $entry['file']; } $entry_line = 'NO_LINE'; if (array_key_exists('line', $entry)) { $entry_line = $entry['line']; } $output .= $entry_file . ':' . $entry_line . ' - ' . $func . PHP_EOL; } return $output; }
Вот «довольно печатный» var_dump
function vdump() { $args = func_get_args(); $backtrace = debug_backtrace(); $code = file($backtrace[0]['file']); echo "<pre style='background: #eee; border: 1px solid #aaa; clear: both; overflow: auto; padding: 10px; text-align: left; margin-bottom: 5px'>"; echo "<b>".htmlspecialchars(trim($code[$backtrace[0]['line']-1]))."</b>\n"; echo "\n"; ob_start(); foreach ($args as $arg) var_dump($arg); $str = ob_get_contents(); ob_end_clean(); $str = preg_replace('/=>(\s+)/', ' => ', $str); $str = preg_replace('/ => NULL/', ' → <b style="color: #000">NULL</b>', $str); $str = preg_replace('/}\n(\s+)\[/', "}\n\n".'$1[', $str); $str = preg_replace('/ (float|int)\((\-?[\d\.]+)\)/', " <span style='color: #888'>$1</span> <b style='color: brown'>$2</b>", $str); $str = preg_replace('/array\((\d+)\) {\s+}\n/', "<span style='color: #888'>array•$1</span> <b style='color: brown'>[]</b>", $str); $str = preg_replace('/ string\((\d+)\) \"(.*)\"/', " <span style='color: #888'>str•$1</span> <b style='color: brown'>'$2'</b>", $str); $str = preg_replace('/\[\"(.+)\"\] => /', "<span style='color: purple'>'$1'</span> → ", $str); $str = preg_replace('/object\((\S+)\)#(\d+) \((\d+)\) {/', "<span style='color: #888'>obj•$2</span> <b style='color: #0C9136'>$1[$3]</b> {", $str); $str = str_replace("bool(false)", "<span style='color:#888'>bool•</span><span style='color: red'>false</span>", $str); $str = str_replace("bool(true)", "<span style='color:#888'>bool•</span><span style='color: green'>true</span>", $str); echo $str; echo "</pre>"; echo "<div class='block tiny_text' style='margin-left: 10px'>"; echo "Sizes: "; foreach ($args as $k => $arg) { if ($k > 0) echo ","; echo count($arg); } echo "</div>"; }
Zend_Debug::dump($var);
Мой любимый фрагмент var_dump
– это тот, который я сделал много лет назад и с тех пор работаю над совершенствованием. Я знаю, что там есть lib, которые создают действительно красивые причуды с аккордеонными меню и все, но я просто хочу простой макет, легко читаемый, может быть, немного HTML, и такой же переносимый, как и один метод кода. Таким образом, моя функция:
function preDump() { // use string "noEcho" to just get a string return only $args = func_get_args(); $doEcho = TRUE; $sb; if ($args) { $sb = '<div style="margin: 1em 0;"><fieldset style="display:inline-block;padding:0em 3em 1em 1em;"><legend><b>preDump: '.count($args).' Parameters Found.</b></legend>'; foreach (func_get_args() as $arg) { if (gettype($arg) == 'string') if ($arg == 'noEcho') { $doEcho = FALSE; $sb = preg_replace('/(preDump: )[0-9]+/', 'preDump: '.(count($args)-1), $sb); continue; } $sb .= '<pre data-type="'.gettype($arg).'"'; switch (gettype($arg)) { case "boolean": case "integer": $sb .= ' data-dump="json_encode"><p style="border-bottom:1px solid;margin:0;padding:0 0 0 1em;"><b>gettype('.gettype($arg).')</b></p><p>'; $sb .= json_encode($arg); break; case "string": $sb .= ' data-dump="echo"><p style="border-bottom:1px solid;margin:0;padding:0 0 0 1em;"><b>gettype('.gettype($arg).')</b></p><p>'; $sb .= $arg; break; default: $sb .= ' data-dump="var_dump"'; if (is_object($arg)) $sb .= 'data-class="'.get_class($arg).'"'; $sb .= '><p style="border-bottom:1px solid;margin:0;padding:0 0 0 1em;"><b>gettype('.gettype($arg).')'; if (is_object($arg)) $sb .= ' ['.get_class($arg).']'; $sb .= '</b></p><p>'; ob_start(); var_dump($arg); $sb .= ob_get_clean(); if (ob_get_length()) ob_end_clean(); } $sb .= '</p></pre>'; } $sb .= '</fieldset></div>'; } else { $sb = '<div style="margin: 1em 0;"><fieldset style="display:inline-block;"><legend><b>preDump: [ERROR]</b></legend><h3>No Parameters Found</h3></fieldset></div>'; } if ($doEcho) echo($sb); return $sb; }
Использование чрезвычайно просто. Он принимает бесконечные параметры. Кроме того, он показывает все в простых preDump
для каждого preDump
, а также разделяет каждый параметр на свой собственный тег pre
, тем самым делая его чистым и легко читаемым. Каждый pre
tag также содержит заголовок, показывающий gettype
каждого параметра, и, если это объект, он также отображает class name
.
Используйте так же просто, как var_dump();
preDump(TRUE, 101, 'this is a string', array( 'array', 'here' ), (object)array ( 'this' => 'is', 'an' => 'object' ), $someXMLvariable);
Вы также можете использовать его для получения дампа в виде простой строки, а затем эха, когда вы сочтете нужным:
$bob = preDump($someParam1, $someParam2, 'noEcho'); // 'noEcho' causes it to return as string only