How can I get the full string of PHP’s getTraceAsString()?

前端 未结 7 1275
南笙
南笙 2020-12-08 10:32

I\'m using getTraceAsString() to get a stack trace but the string is being truncated for some reason.

Example, an exception is thrown and I log the stri

相关标签:
7条回答
  • 2020-12-08 11:03

    There is also the excellent jTraceEx recipe by Ernest Vogelsinger at https://www.php.net/manual/exception.gettraceasstring.php#114980, that supports chained exceptions and is formatted in a Java-like manner.

    Here is a comparison taken directly from his comment on php.net :

    Exception::getTraceAsString :

    #0 /var/htdocs/websites/sbdevel/public/index.php(70): seabird\test\C->exc()
    #1 /var/htdocs/websites/sbdevel/public/index.php(85): seabird\test\C->doexc()
    #2 /var/htdocs/websites/sbdevel/public/index.php(89): seabird\test\fail2()
    #3 /var/htdocs/websites/sbdevel/public/index.php(93): seabird\test\fail1()
    #4 {main}
    

    jTraceEx :

    Exception: Thrown from class C
     at seabird.test.C.exc(index.php:78)
     at seabird.test.C.doexc(index.php:70)
     at seabird.test.fail2(index.php:85)
     at seabird.test.fail1(index.php:89)
     at (main)(index.php:93)
    Caused by: Exception: Thrown from class B
     at seabird.test.B.exc(index.php:64)
     at seabird.test.C.exc(index.php:75)
     ... 4 more
    Caused by: Exception: Thrown from class A
     at seabird.test.A.exc(index.php:46)
     at seabird.test.B.exc(index.php:61)
     ... 5 more
    
    0 讨论(0)
  • 2020-12-08 11:10

    I created this function to return a stack trace with no truncated strings:

    function getExceptionTraceAsString($exception) {
        $rtn = "";
        $count = 0;
        foreach ($exception->getTrace() as $frame) {
            $args = "";
            if (isset($frame['args'])) {
                $args = array();
                foreach ($frame['args'] as $arg) {
                    if (is_string($arg)) {
                        $args[] = "'" . $arg . "'";
                    } elseif (is_array($arg)) {
                        $args[] = "Array";
                    } elseif (is_null($arg)) {
                        $args[] = 'NULL';
                    } elseif (is_bool($arg)) {
                        $args[] = ($arg) ? "true" : "false";
                    } elseif (is_object($arg)) {
                        $args[] = get_class($arg);
                    } elseif (is_resource($arg)) {
                        $args[] = get_resource_type($arg);
                    } else {
                        $args[] = $arg;
                    }   
                }   
                $args = join(", ", $args);
            }
            $rtn .= sprintf( "#%s %s(%s): %s(%s)\n",
                                     $count,
                                     $frame['file'],
                                     $frame['line'],
                                     $frame['function'],
                                     $args );
            $count++;
        }
        return $rtn;
    }
    

    Alternatively, you could edit the php source where it is truncating the output: https://github.com/php/php-src/blob/master/Zend/zend_exceptions.c#L392

    0 讨论(0)
  • 2020-12-08 11:17

    Some better version https://stackoverflow.com/a/6076667/194508 is here https://gist.github.com/1437966 added class to output.

    0 讨论(0)
  • 2020-12-08 11:17

    If you can get away with var_dump() an easy solution is:

    try {
       ...
    } catch (Exception $e)
       var_dump($e->getTrace());
    }
    

    Stolen from this great answer by Andre

    0 讨论(0)
  • 2020-12-08 11:21

    That solution is good but in my case it threw an error because my trace has internal functions in it. I added a few lines of code to check for that so the trace functions still works.

    function getExceptionTraceAsString($exception) {
        $rtn = "";
        $count = 0;
        foreach ($exception->getTrace() as $frame) {
    
    
            $args = "";
            if (isset($frame['args'])) {
                $args = array();
                foreach ($frame['args'] as $arg) {
                    if (is_string($arg)) {
                        $args[] = "'" . $arg . "'";
                    } elseif (is_array($arg)) {
                        $args[] = "Array";
                    } elseif (is_null($arg)) {
                        $args[] = 'NULL';
                    } elseif (is_bool($arg)) {
                        $args[] = ($arg) ? "true" : "false";
                    } elseif (is_object($arg)) {
                        $args[] = get_class($arg);
                    } elseif (is_resource($arg)) {
                        $args[] = get_resource_type($arg);
                    } else {
                        $args[] = $arg;
                    }
                }
                $args = join(", ", $args);
            }
            $current_file = "[internal function]";
            if(isset($frame['file']))
            {
                $current_file = $frame['file'];
            }
            $current_line = "";
            if(isset($frame['line']))
            {
                $current_line = $frame['line'];
            }
            $rtn .= sprintf( "#%s %s(%s): %s(%s)\n",
                $count,
                $current_file,
                $current_line,
                $frame['function'],
                $args );
            $count++;
        }
        return $rtn;
    }
    
    0 讨论(0)
  • 2020-12-08 11:23

    You can print the backtrace with

    debug_print_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
    

    It does not truncate.

    Example print would be

    #0  W3\\Sausage\\Mushroom->setCredentials() called at [/sausage/common/library/W3/Vzaar/Api.php:40]
    #1  W3\\Sausage\\Mushroom->__construct() called at [/sausage/common/modules/video.mod.php:24]
    #2  ModVideo->__construct() called at [/sausage/common/core/modules.core.php:133]
    #3  Modules->__get() called at [/sausage/common/search/Classified/ESAdapter.php:399]
    #4  Base\\Search\\Classified\\ESAdapter->getVideoInfo() called at [/sausage/common/search/Classified/ESAdapter.php:436]
    #5  Base\\Search\\Classified\\ESAdapter->fillDataSet() called at [/sausage/common/search/Adapter.php:58]
    
    0 讨论(0)
提交回复
热议问题