php - habilitar - short_open_tag off
¿Cómo puedo obtener PHP para generar una traza inversa en caso de errores? (12)
Error de PHP
Este es un mejor informe de errores para PHP escrito en PHP. ¡No se requieren extensiones adicionales!
Es trivial de usar cuando todos los errores se muestran en el navegador para las solicitudes AJAXy normales (en estado de pausa). Luego, todos los errores le proporcionan una traza inversa y un contexto de código en toda la traza de pila, incluidos los argumentos de función, las variables de servidor.
Todo lo que necesita hacer es incluir un solo archivo y llamar a la función (al principio de su código), por ejemplo
require(''php_error.php'');
/php_error/reportErrors();
Vea las capturas de pantalla:
Página de inicio: http://phperror.net/
GitHub: https://github.com/JosephLenton/PHP-Error
Mi tenedor (con correcciones adicionales): https://github.com/kenorb-contrib/PHP-Error
Debug clase PHP
Una clase completa de depuración de PHP, con soporte para Excepción, Errores, Alertas (del usuario), líneas de código y marcadores de resaltado.
Ejemplo de uso:
<?php
include( dirname(dirname(__FILE__)) . ''/src/Debug.php'' );
//Catch all
Debug::register();
//Generate an errors
if( this_function_does_not_exists( ) )
{
return false;
}
?>
Manejo de errores en PHP
El siguiente ejemplo muestra el manejo de las excepciones internas al desencadenar errores y manejarlos con una función definida por el usuario:
Forma más corta (PHP):
<?php
function e($number, $msg, $file, $line, $vars) {
print_r(debug_backtrace());
die();
}
set_error_handler(''e'');
Forma más larga (PHP):
// 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: solo puede tener una excepción de error a la vez. Cuando llame a la función set_error_handler () devolverá el nombre del antiguo manejador de errores. Puede almacenar esto y llamarlo usted mismo desde su manejador de errores, lo que le permite tener múltiples manejadores de errores.
XDebug
Para una solución más avanzada, puede usar la extensión Xdebug para PHP.
De forma predeterminada, cuando se carga XDebug, debe mostrar automáticamente la traza inversa en caso de cualquier error fatal. O rastrea en el archivo (xdebug.auto_trace) para tener una traza inversa muy grande de toda la solicitud o hacer el perfil (xdebug.profiler_enable) u otras configuraciones . Si el archivo de rastreo es demasiado grande, puede usar xdebug_start_trace () y xdebug_stop_trace () para volcar el rastreo parcial.
Instalación
Usando 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 configuración de la mina:
[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.
Drupal 6 y 7
Con Devel habilitado:
/**
* Implements hook_watchdog().
*/
function foo_watchdog($log_entry) {
if ($log_entry[''type''] == ''php'' && $log_entry[''severity''] <= WATCHDOG_WARNING) {
function_exists(''dd'') && dd(debug_backtrace());
}
}
La función anterior registrará las trazas inversas de cada error en un archivo temporal ( /tmp/drupal_debug.txt
de forma predeterminada).
O busque el archivo a través de: drush eval "echo file_directory_temp() . ''/drupal_debug.txt''
.
Sin Devel habilitado, use el enfoque de la vieja escuela: var_dump(debug_backtrace());
en lugar de dd()
.
Tratar de depurar PHP utilizando sus mensajes de error de línea actual predeterminados es horrible. ¿Cómo puedo obtener PHP para generar una traza inversa (seguimiento de la pila) cuando se producen errores?
Acabo de intentar establecer una variable de sesión que contenga los contenidos de debug_backtrace () en la línea ofensiva, y luego imprimirlo usando register_shutdown_function (). Trabajado como un encanto.
Así es como lo haces:
set_error_handler(function($errorType){
if(error_reporting() & $errorType){
?><pre><?
debug_print_backtrace();
?></pre><?
}
}) ;
Requiere PHP 5.3+ ya que usa un cierre. Si necesita soporte PHP más bajo, convierta el cierre en una función normal.
Mi script para instalar un controlador de errores que produce una traza inversa:
<?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 afectar varios ''Errores fatales de PHP'' , ya que Zend en su sabiduría decidió que estos ignorarían a set_error_handler()
. Así que aún obtienes errores inútiles de ubicación final con esos.
Puedes usar debug_backtrace
Si no puede instalar un depurador, use esta función alrededor del error fatal para obtener la "pila fatal". Compruebe el código y el ejemplo a continuación que explican mejor cómo usarlo:
// Give an extra parameter to the filename
// to save multiple log files
function _fatalog_($extra = false)
{
static $last_extra;
// CHANGE THIS TO: A writeable filepath in your system...
$filepath = ''/var/www/html/sites/default/files/fatal-''.($extra === false ? $last_extra : $extra).''.log'';
if ($extra===false) {
unlink($filepath);
} else {
// we write a log file with the debug info
file_put_contents($filepath, json_encode(debug_backtrace()));
// saving last extra parameter for future unlink... if possible...
$last_extra = $extra;
}
}
Aquí hay un ejemplo de cómo usarlo:
// A function which will produce a fatal error
function fatal_example()
{
_fatalog_(time()); // writing the log
$some_fatal_code = array()/3; // fatality!
_fatalog_(); // if we get here then delete last file log
}
Finalmente para leer el contenido del registro ...
var_dump(json_decode(file_get_contents(''/path/to-the-fatal.log'')));
¡Espero que ayude!
PHP DeBugger también hace una traza inversa similar a PHP Error con más opciones.
Si lo desea, puede hacer fácilmente los suyos con set_error_handler
y debug_backtrace
set_error_handler ($error_handler, error_reporting);
/**
* @var int $errno the error number
* @var string $errstr the error message
* @var string $errfile the error file
* @var int $errline the line of the error
*/
$error_handler = function($errno, $errstr, $errfile, $errline){
$trace = debug_backtrace();
array_shift($backtrace);//remove the stack about this handler
foreach($trace as $k => $v){
//parse your backtrace
}
}
También tenga en cuenta que para las pilas internas en el backtrace algunas de las teclas no se establecerán. Asegúrese de verificar si la clave existe antes de hacer algo con ella si tiene todos los errores :)
El error PHP le dará un seguimiento de pila para sus errores, y es mucho más bonito que xDebug.
También funcionará para solicitudes ajax también.
set_error_handler()
+ debug_backtrace()
+ debug_print_backtrace()
en PHP5
$backtrace = debug_backtrace();
Escribí un pequeño artículo sobre retroceder hace un tiempo