让我们面对现实,debug_backtrace()
输出不是很漂亮。有没有人编写过包装器?
你最喜欢的是什么var_dump()
(可以在商业项目中使用,所以没有GPL(虽然LGPL没问题))
另请参阅:A more pretty/informative Var_dump alternative in 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 = is_array($trace['args']) ? implode(", ",$trace['args']) : "";
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;
}
答案 0 :(得分:9)
您还有kint
(github repo)composer
存储库上有packagist
个包
因此,无论是手动下载库还是使用composer
,都只需要:
$ composer init
$ composer require raveren/kint
$ composer install
然后,我更喜欢在我的main(first)包含文件中使用这个简单的处理程序而不是ini_set('display_errors', 'On');
:
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 {
...
}
在Apache的Virtualhost(__project_env__
)中设置SetEnv __project_env__ "DEV"
,以免污染项目所在的git
存储库的不同分支,其中包含基本{{1}的配置项1}}
以下是跟踪外观(每个步骤均可折叠)的屏幕截图:
答案 1 :(得分:6)
Xdebug extension可以print stacktraces具有可配置的详细程度。
它还提供了一些additional var_dump() features,例如语法着色:
修改强>
关于将Xdebug纳入商业项目。
Xdebug license只有几个术语,看起来非常宽松。
Xdebug是C扩展名。因此,在项目中重新分配它或部分它可能有点困难。根据您的要求,我看到了几个选项:
答案 2 :(得分:5)
这是我的漂亮的打印包装器,用于非浏览器输出,即错误日志或控制台:
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;
}
答案 3 :(得分:3)
// allow CORS:
app.use(function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', 'http://localhost:8000');
next();
});
答案 4 :(得分:1)
这是一个“漂亮的印刷品”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>";
}
答案 5 :(得分:1)
Zend_Debug::dump($var);
答案 6 :(得分:1)
将我的答案添加到此处的其余答案中。
如果安装了bootstrap和jquery,它会更加有用和紧凑,但不是必需的。
function prettyPrintBackTrace() {
$backtrace = "\n<b><u>Full Backtrace</u></b>\n<script>function toggleBackTraceTwirl(self) {\$('span', self).toggleClass('glyphicon-menu-up glyphicon-menu-down');}</script>";
foreach (debug_backtrace() as $key => $trace) {
if(($trace['function'] ==__FUNCTION__) || ($trace['function'] == "fail")) {continue;}
$class = (array_key_exists('class', $trace) ? "class <u>({$trace['class']})</u>" : false);
$exp = explode("/",$trace['file']);
$exp[count($exp)-1] = "<b>" . end($exp) . "</b>";;
$filename = implode("/",array_splice($exp, -4));
$backtrace .= "/{$filename}:{$trace['line']}, ";
if((isset($trace['args'])) && (is_array($trace['args']))) {
if( (is_string($trace['args'][0])) && (substr($trace['args'][0],-4) == ".php") && (count($trace['args'] == 1)) ) {
// It was most likely a php include of some sort.
$exp = explode("/",$trace['args'][0]);
$filename = implode("/",array_splice($exp, -2));
$backtrace .= "function <i>{$trace['function']}(<b>{$filename}</b>)</i>\n";
} else {
// Finish the line and move on.
$backtrace .= "function <i>{$trace['function']}()</i> <a href='#' data-target='#backtraceparameters{$key}' onClick='toggleBackTraceTwirl(this)' data-toggle='collapse'><span class='glyphicon glyphicon-menu-down'></span></a>\n";
$backtrace .= "<div id='backtraceparameters{$key}' class='collapse'>";
$args = array();
foreach($trace['args'] as $key => $val) {
if($val) $args[(!is_numeric($key) ? "key" : false)] = $val;
}
foreach($args as $count => $a) {
$backtrace .= ($count != (count($args) -1) ? "├" : "└");
$value = $a;
if($a === true) $value = "<i>true</i>";
if($a === false) $value = "<i>f alse</i>";
$backtrace .= "─ ".(!is_numeric($count) ? $count." " : false).var_export($value,1)."\n";
}
$backtrace .= "</div>";
}
}
}
return $backtrace;
}
我希望能对某人有所帮助。我试图使其尽可能紧凑。
答案 7 :(得分:0)
我最喜欢的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;
}
使用非常简单。它需要无限的参数。此外,它还为所调用的每个fieldsets
显示简单preDump
内的所有内容,并将每个参数分隔为自己的pre
标记,从而使其清晰易读。每个pre
标记还包含一个标题,显示每个参数的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