2010-11-26 45 views
12

讓我們面對它,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 = ''; 
     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; 
} 
+0

請不要將答案(如自己的解決方案)編輯到「問題」字段中;我們寧願將頁面的兩個部分嚴格分開。相反,如果您的信息超出了當前列出的答案,您[鼓勵回答您自己的問題](http://stackoverflow.com/help/self-answer)。 – IMSoP 2017-02-22 17:47:45

回答

6

Xdebug extension可以用配置的程度冗長的print stacktraces

Xdebug stacktrace image

它還提供了一些additional var_dump() features如語法着色:

Colored var_dump()

編輯:

關於在商業項目列入Xdebug的的。

Xdebug license只有幾個詞,似乎很寬容。

Xdebug是一個C擴展。因此,在您的項目中將其重新分發或部分分發可能有點困難。根據您的要求我看到幾個選項:

  • 讓你的最終用戶從Linux分發包或DLL從網站上安裝Xdebug的
  • 分發.dll和。所以對於所有支持的平臺文件
  • 讓你的最終用戶建立的源代碼
  • 分發PHP
+0

+1,但可以作爲獨立代碼嗎? – Mawg 2010-11-26 02:55:24

2

這裏有一個 「漂亮的打印」 的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/', ' &rarr; <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&bull;$1</span> <b style='color: brown'>[]</b>", $str); 
     $str = preg_replace('/ string\((\d+)\) \"(.*)\"/', " <span style='color: #888'>str&bull;$1</span> <b style='color: brown'>'$2'</b>", $str); 
     $str = preg_replace('/\[\"(.+)\"\] => /', "<span style='color: purple'>'$1'</span> &rarr; ", $str); 
     $str = preg_replace('/object\((\S+)\)#(\d+) \((\d+)\) {/', "<span style='color: #888'>obj&bull;$2</span> <b style='color: #0C9136'>$1[$3]</b> {", $str); 
     $str = str_replace("bool(false)", "<span style='color:#888'>bool&bull;</span><span style='color: red'>false</span>", $str); 
     $str = str_replace("bool(true)", "<span style='color:#888'>bool&bull;</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>"; 

} 
+0

+1我會試試看。謝謝 – Mawg 2010-11-26 02:55:44

1
+0

+1,但可以作爲獨立代碼使用嗎? – Mawg 2010-11-26 03:22:55

+1

@Mawg - 你可以使用這個打包器:http://epic.codeutopia.net/pack/它可以讓你選擇你想要的組件,並自動包含它們的依賴關係。儘可能將ZF解耦。 – karim79 2010-11-26 11:00:44

+0

+1聽起來不錯。謝謝 – Mawg 2010-11-27 14:50:45

6

這裏的自定義生成是用於非瀏覽器輸出我漂亮的印刷包裝,即錯誤日誌或控制檯:

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; 
} 
9

你也有kintgithub repo),其具有composer包上packagist

因此,無論手動或使用composer下載庫,它只是一個的事情:

$ composer init 
$ composer require raveren/kint 
$ composer install 

然後,而不是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 { 
... 
} 

隨着__project_env__ Apache的虛擬主機()被設定爲不污染git儲存庫,該項目的生活與它們的本質配置項的不同分支environmental

  • 在DEV:讓我的調試
  • 在PROD,它的默認

這裏沉默是如何跟蹤外觀的截圖(每一步都是可摺疊):

Kint stack trace

0

我的最愛var_dump snippet是我多年前製作的,自那以後一直致力於完善。我知道那裏有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調用的簡單fieldsets內的所有內容,並將每個參數分隔爲自己的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 
3

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; 
}