Is there a Pretty Print Stack Dump?

后端 未结 8 1867
半阙折子戏
半阙折子戏 2021-02-07 17:41

Let\'s face it, debug_backtrace() output is not very pretty. Did anyone code a wrapper?

And what\'s your favourite pretty var_dump() (which is

相关标签:
8条回答
  • 2021-02-07 18:05

    You also have kint (github repo) which has a composer package on the packagist repository

    So either download the library manually or with composer, it's just a matter of :

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

    Then, instead of ini_set('display_errors', 'On');, I prefer to use this simple handler in my main (first) include file :

    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 {
     ...
    }
    

    With __project_env__ being set in Apache's Virtualhost (SetEnv __project_env__ "DEV") so as not to pollute the different branches of the git repository where the project lives with configuration items which are by essence environmental

    • In DEV : i get my debugging
    • In PROD, it's silent by default

    Here is a screenshot of how the trace looks (each step is collapsible):


    (source: github.io)

    0 讨论(0)
  • 2021-02-07 18:05

    jhurliman's pretty print stackTrace method above is really great. But for me it was generating lots of PHP Warnings that were also cluttering up the log. I added a little more error and type checking which results in a very nice stack trace in the logs. Here is the modified version of jhurliman's code:

    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;
    }
    
    0 讨论(0)
  • 2021-02-07 18:06

    Here's a "pretty print" 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 讨论(0)
  • 2021-02-07 18:07
    Zend_Debug::dump($var);
    

    http://framework.zend.com/manual/en/zend.debug.html

    0 讨论(0)
  • 2021-02-07 18:08

    My favorite var_dump snippet is one I made years ago and have been working on perfecting ever since. I know there are lib's out there that create really pretty fancy dumps with accordion menus and all, but I just want a simple layout, easy to read, maybe a little HTML, and as portable as a single code-snippet method can be. Thus my function:

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

    Use is extremely simple. It takes infinite parameters. Also, it shows everything within simple fieldsets for each preDump called, as well as separating each parameter into its own pre tag, thus making it clean and easy to read. Each pre tag also contains a header showing the gettype of each parameter, and, if it's an object, it will also show the class name.

    Use as easy as var_dump();

    preDump(TRUE, 101, 'this is a string', array( 'array', 'here' ), (object)array ( 'this' => 'is', 'an' => 'object' ), $someXMLvariable);
    

    You can also use it to get the dump as a simple string and then echo when you see fit:

    $bob = preDump($someParam1, $someParam2, 'noEcho'); // 'noEcho' causes it to return as string only
    
    0 讨论(0)
  • 2021-02-07 18:12

    The Xdebug extension can print stacktraces with a configurable degree of verbosity.

    Xdebug stacktrace image

    It also offers some additional var_dump() features such as syntax coloring:

    Colored var_dump()

    Edit:

    Regarding the inclusion of Xdebug in a commercial project.

    The Xdebug license has only a few terms and seems pretty permissive.

    Xdebug is a C extension. As such re-distributing it or part of it in your project may be somewhat difficult. Depending on your requirements I see a few options:

    • Have your end user install Xdebug from a Linux distribution package or a DLL from the site
    • Distribute .dll and .so files for all supported platforms
    • Have your end user build the source code
    • Distribute a custom build of PHP
    0 讨论(0)
提交回复
热议问题