362 votos

¿Cómo capturar un Error Fatal de PHP

Puedo usar set_error_handler() para la captura de la mayoría de los errores de PHP, pero no funciona fatal (E\_ERROR) errores, tales como llamar a una función que no existe. Hay otra manera de detectar estos errores?

Estoy tratando de llamar a mail() de todos los errores y estoy ejecutando PHP 5.2.3.

453voto

user259973 Puntos 3255

Registro de errores fatales utilizando register_shutdown_function, el cual requiere de PHP 5.2+:

register_shutdown_function( "fatal_handler" );

function fatal_handler() {
  $errfile = "unknown file";
  $errstr  = "shutdown";
  $errno   = E_CORE_ERROR;
  $errline = 0;

  $error = error_get_last();

  if( $error !== NULL) {
    $errno   = $error["type"];
    $errfile = $error["file"];
    $errline = $error["line"];
    $errstr  = $error["message"];

    error_mail(format_error( $errno, $errstr, $errfile, $errline));
  }
}

Se ha de definir el error_mail y format_error funciones. Por ejemplo:

function format_error( $errno, $errstr, $errfile, $errline ) {
  $trace = print_r( debug_backtrace( false ), true );

  $content  = "<table><thead bgcolor='#c8c8c8'><th>Item</th><th>Description</th></thead><tbody>";
  $content .= "<tr valign='top'><td><b>Error</b></td><td><pre>$errstr</pre></td></tr>";
  $content .= "<tr valign='top'><td><b>Errno</b></td><td><pre>$errno</pre></td></tr>";
  $content .= "<tr valign='top'><td><b>File</b></td><td>$errfile</td></tr>";
  $content .= "<tr valign='top'><td><b>Line</b></td><td>$errline</td></tr>";
  $content .= "<tr valign='top'><td><b>Trace</b></td><td><pre>$trace</pre></td></tr>";
  $content .= '</tbody></table>';

  return $content;
}

El uso de Swift Mailer escribir la error_mail función.

Ver también:

95voto

keparo Puntos 13747

PHP no ofrecerle cualquiera de los medios convencionales para la captura de errores fatales, ya que realmente no debería ser atrapado. Es decir, usted no debe tratar de recuperarse de un error fatal. Cadena de coincidencia de un búfer de salida es definitivamente desacertado.

Llamar a la función mail() de dentro de un controlador de errores de método resultar problemática, también. Si usted tenía un montón de errores, su servidor de correo podría ser cargado con el trabajo, y usted podría encontrarse con un retorcido bandeja de entrada. Para evitar esto, usted podría considerar la ejecución de un cron para digitalizar los registros de error periódicamente y enviar notificaciones en consecuencia. También te puede interesar buscar en el sistema de software de monitoreo, tales como Nagios.


Hablar con el poco acerca del registro de una función de apagado:

Es cierto que se puede registrar una función de apagado, y que es una buena respuesta.

El punto aquí es que usted no debe tratar de recuperarse de errores fatales, especialmente mediante el uso de una expresión regular en contra de su búfer de salida. Yo estaba respondiendo a la aceptada respuesta, que vinculada a una sugerencia en php.net el cual ha sido modificado o eliminado.

La propuesta fue utilizar una expresión regular contra el búfer de salida durante el manejo de excepciones, y en el caso de un error grave (detectado por la coincidencia en contra de lo que configura el texto de error que podría estar esperando a), trate de hacer algún tipo de recuperación o la continuación de la tramitación. Que no sería una práctica recomendada (creo que por eso no puedo encontrar la sugerencia original, también. Estoy bien vistas, o la comunidad de php tiró abajo).

Cabe destacar que las versiones más recientes de PHP (alrededor de 5.1) parecen llamar a la función de apagado antes, antes de que el almacenamiento en búfer de salida de devolución de llamada es envoked. En la versión 5 y anteriores, que el fin estaba a la inversa (el búfer de salida de devolución de llamada fue seguido por la función de apagado). También, desde alrededor de 5.0.5 (que es mucho antes de que el interrogador de la versión 5.2.3), los objetos se descargan bien antes registrado función de apagado se llama, entonces usted no será capaz de confiar en sus objetos en memoria para hacer mucho de nada.

Para registrar una función de apagado está muy bien, pero el tipo de tareas que deben ser realizadas por una función de apagado son probablemente limitada a un puñado de suave procedimientos de cierre.

La clave aquí es sólo de algunas palabras de sabiduría para cualquier persona que se topa con esta pregunta y ve el asesoramiento en el original aceptado respuesta. No regex su búfer de salida.

81voto

periklis Puntos 4978

acaba de llegar con esta solución (php 5.2.0+):

register_shutdown_function('shutdownFunction');

function shutDownFunction() { 
    $error = error_get_last();
    if ($error['type'] == 1) {
        //do your stuff     
    } 
}

Diferentes tipos de error definidos en http://www.php.net/manual/en/errorfunc.constants.php

24voto

sakhunzai Puntos 2399

Así que parece posible para la captura de Errores Fatales de otra manera :)

ob_start('fatal_error_handler');

function fatal_error_handler($buffer){
    $error=error_get_last();
    if($error['type'] == 1){
        // type, message, file, line
        $newBuffer='<html><header><title>Fatal Error </title></header>
                    <style>                 
                    .error_content{                     
                        background: ghostwhite;
                        vertical-align: middle;
                        margin:0 auto;
                        padding:10px;
                        width:50%;                              
                     } 
                     .error_content label{color: red;font-family: Georgia;font-size: 16pt;font-style: italic;}
                     .error_content ul li{ background: none repeat scroll 0 0 FloralWhite;                   
                                border: 1px solid AliceBlue;
                                display: block;
                                font-family: monospace;
                                padding: 2%;
                                text-align: left;
                      }
                    </style>
                    <body style="text-align: center;">  
                      <div class="error_content">
                          <label >Fatal Error </label>
                          <ul>
                            <li><b>Line</b> '.$error['line'].'</li>
                            <li><b>Message</b> '.$error['message'].'</li>
                            <li><b>File</b> '.$error['file'].'</li>                             
                          </ul>

                          <a href="javascript:history.back()"> Back </a>                          
                      </div>
                    </body></html>';

        return $newBuffer;

    }

    return $buffer;

}

14voto

hipertracker Puntos 1417

Usted no puede lanzar la excepción dentro registrado función de apagado como que:

<?php
function shutdown() {
 if (($error = error_get_last())) {
   ob_clean();
   throw new Exception("fatal error");
  }
}

try {
  $x = null;
  $x->method()
} catch(Exception $e) {
  # this won't work
}
?>

Pero usted puede capturar y redirigir la petición a otra página.

<?php
function shutdown() {
 if (($error = error_get_last())) {
   ob_clean();
   # raport the event, send email etc.
   header("Location: http://localhost/error-capture");
   # from /error-capture, you can use another redirect, to e.g. home page
  }
}
register_shutdown_function('shutdown');

$x = null;
$x->method()
?>

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