49 votos

¿Cómo puedo obtener PHP para producir una traza sobre errores?

Tratando de depuración de PHP usando su valor predeterminado actual de la línea-sólo los mensajes de error es horrible. ¿Cómo puedo obtener PHP para producir una traza (seguimiento de pila) cuando los errores son producidos?

47voto

chaos Puntos 69029

Mi script para la instalación de un controlador de error que produce una traza:

<?php
function process_error_backtrace($errno, $errstr, $errfile, $errline, $errcontext) {
    if(!(error_reporting() & $errno))
        return;
    switch($errno) {
    case E_WARNING      :
    case E_USER_WARNING :
    case E_STRICT       :
    case E_NOTICE       :
    case E_USER_NOTICE  :
        $type = 'warning';
        $fatal = false;
        break;
    default             :
        $type = 'fatal error';
        $fatal = true;
        break;
    }
    $trace = array_reverse(debug_backtrace());
    array_pop($trace);
    if(php_sapi_name() == 'cli') {
        echo 'Backtrace from ' . $type . ' \'' . $errstr . '\' at ' . $errfile . ' ' . $errline . ':' . "\n";
        foreach($trace as $item)
            echo '  ' . (isset($item['file']) ? $item['file'] : '<unknown file>') . ' ' . (isset($item['line']) ? $item['line'] : '<unknown line>') . ' calling ' . $item['function'] . '()' . "\n";
    } else {
        echo '<p class="error_backtrace">' . "\n";
        echo '  Backtrace from ' . $type . ' \'' . $errstr . '\' at ' . $errfile . ' ' . $errline . ':' . "\n";
        echo '  <ol>' . "\n";
        foreach($trace as $item)
            echo '    <li>' . (isset($item['file']) ? $item['file'] : '<unknown file>') . ' ' . (isset($item['line']) ? $item['line'] : '<unknown line>') . ' calling ' . $item['function'] . '()</li>' . "\n";
        echo '  </ol>' . "\n";
        echo '</p>' . "\n";
    }
    if(ini_get('log_errors')) {
        $items = array();
        foreach($trace as $item)
            $items[] = (isset($item['file']) ? $item['file'] : '<unknown file>') . ' ' . (isset($item['line']) ? $item['line'] : '<unknown line>') . ' calling ' . $item['function'] . '()';
        $message = 'Backtrace from ' . $type . ' \'' . $errstr . '\' at ' . $errfile . ' ' . $errline . ': ' . join(' | ', $items);
        error_log($message);
    }
    if($fatal)
        exit(1);
}

set_error_handler('process_error_backtrace');
?>

Advertencia: es impotente para afectar a diversos 'PHP Errores Fatales', desde Zend en su sabiduría, decidió que estos ignoran set_error_handler(). Así que usted todavía consigue inútil final-ubicación-sólo los errores con los.

45voto

patcoll Puntos 680

Xdebug imprime las trazas de una tabla de errores, y usted no tiene que escribir ningún código PHP para ponerlo en práctica.

La desventaja es que tienes que instalar es como una extensión de PHP.

27voto

kenorb Puntos 2464

La gestión de errores en PHP

El siguiente ejemplo muestra el manejo interno de excepciones mediante la activación de errores y manejo de ellos con una función definida por el usuario:

Camino más corto:

<?php
function e($number, $msg, $file, $line, $vars) {
   print_r(debug_backtrace());
   die();
}
set_error_handler('e');

Camino más largo:

// set to the user defined error handler
$old_error_handler = set_error_handler("myErrorHandler");

// error handler function
function myErrorHandler($errno, $errstr, $errfile, $errline)
{
    if (!(error_reporting() & $errno)) {
        // This error code is not included in error_reporting
        return;
    }

    switch ($errno) {
    case E_USER_ERROR:
        echo "<b>My ERROR</b> [$errno] $errstr<br />\n";
        echo "  Fatal error on line $errline in file $errfile";
        echo ", PHP " . PHP_VERSION . " (" . PHP_OS . ")<br />\n";
        echo "Aborting...<br />\n";
        var_dump(debug_backtrace());
        exit(1);
        break;

    case E_USER_WARNING:
        echo "<b>My WARNING</b> [$errno] $errstr<br />\n";
        break;

    case E_USER_NOTICE:
        echo "<b>My NOTICE</b> [$errno] $errstr<br />\n";
        break;

    default:
        echo "Unknown error type: [$errno] $errstr<br />\n";
        break;
    }

    /* Don't execute PHP internal error handler */
    return true;
}

Ver: http://www.php.net/manual/en/function.set-error-handler.php

Nota: sólo puede tener un error de excepción en un momento. Cuando usted llame a la set_error_handler() la función devolverá el nombre de la antigua controlador de errores. Usted puede almacenar esta y llame usted mismo a partir de su controlador de error – lo que permite tener varios controladores de error.


XDebug

Para obtener más avanzada solución, puede utilizar XDebug extensión para PHP.

Por defecto, cuando XDebug está cargado, debe mostrar automáticamente la traza en caso de cualquier error fatal. O se traza en un archivo (xdebug.auto_trace) para tener una muy grande traza de la solicitud de todo o hacer el perfilado (xdebug.profiler_enable) o otros ajustes. Si el archivo de traza es demasiado grande, puede utilizar xdebug_start_trace() y xdebug_stop_trace() para el volcado de los parciales de seguimiento.

Instalación

El uso de los PECL:

pecl install xdebug

En Linux:

sudo apt-get install php5-xdebug

En Mac (con Homebrew):

brew tap josegonzalez/php
brew search xdebug
php53-xdebug

Ejemplo de la mina de configuración:

[xdebug]

; Extensions
extension=xdebug.so
; zend_extension="/YOUR_PATH/php/extensions/no-debug-non-zts-20090626/xdebug.so"
; zend_extension="/Applications/MAMP/bin/php/php5.3.20/lib/php/extensions/no-debug-non-zts-20090626/xdebug.so" ; MAMP

; Data
xdebug.show_exception_trace=1       ; bool: Show a stack trace whenever an exception is raised.
xdebug.collect_vars = 1             ; bool: Gather information about which variables are used in a certain scope.
xdebug.show_local_vars=1            ; int: Generate stack dumps in error situations.
xdebug.collect_assignments=1        ; bool: Controls whether Xdebug should add variable assignments to function traces.
xdebug.collect_params=4             ; int1-4: Collect the parameters passed to functions when a function call is recorded.
xdebug.collect_return=1             ; bool: Write the return value of function calls to the trace files.
xdebug.var_display_max_children=256 ; int: Amount of array children and object's properties are shown.
xdebug.var_display_max_data=1024    ; int: Max string length that is shown when variables are displayed.
xdebug.var_display_max_depth=3      ; int: How many nested levels of array/object elements are displayed.
xdebug.show_mem_delta=0             ; int: Show the difference in memory usage between function calls.

; Trace
xdebug.auto_trace=0                 ; bool: The tracing of function calls will be enabled just before the script is run.
xdebug.trace_output_dir="/var/log/xdebug" ; string: Directory where the tracing files will be written to.
xdebug.trace_output_name="%H%R-%s-%t"     ; string: Name of the file that is used to dump traces into.

; Profiler
xdebug.profiler_enable=0            ; bool: Profiler which creates files read by KCacheGrind.
xdebug.profiler_output_dir="/var/log/xdebug"  ; string: Directory where the profiler output will be written to.
xdebug.profiler_output_name="%H%R-%s-%t"      ; string: Name of the file that is used to dump traces into.
xdebug.profiler_append=0            ; bool: Files will not be overwritten when a new request would map to the same file.

; CLI
xdebug.cli_color=1                  ; bool: Color var_dumps and stack traces output when in CLI mode.

; Remote debugging
xdebug.remote_enable=off            ; bool: Try to contact a debug client which is listening on the host and port.
xdebug.remote_autostart=off         ; bool: Start a remote debugging session even GET/POST/COOKIE variable is not present.
xdebug.remote_handler=dbgp          ; select: php3/gdb/dbgp: The DBGp protocol is the only supported protocol.
xdebug.remote_host=localhost        ; string: Host/ip where the debug client is running.
xdebug.remote_port=9000             ; integer: The port to which Xdebug tries to connect on the remote host.
xdebug.remote_mode=req              ; select(req,jit): Selects when a debug connection is initiated.
xdebug.idekey="xdebug-cli"          ; string: IDE Key Xdebug which should pass on to the DBGp debugger handler.
xdebug.remote_log="/var/log/xdebug.log" ; string: Filename to a file to which all remote debugger communications are logged.

7voto

Tim Puntos 41

Acabo de intentar establecer una variable de sesión que contiene el contenido de debug_backtrace() en la línea incorrecta, entonces la impresión de que el uso de register_shutdown_function(). Trabajó como un encanto.

3voto

Mythica Puntos 735

Usted puede utilizar debug_backtrace

Iteramos.com

Iteramos es una comunidad de desarrolladores que busca expandir el conocimiento de la programación mas allá del inglés.
Tenemos una gran cantidad de contenido, y también puedes hacer tus propias preguntas o resolver las de los demás.

Powered by:

X