570 votes

Comment pour attraper un PHP Fatal Error

Je peux utiliser pour attraper la plupart des erreurs PHP, mais il ne fonctionne pas pour fatal ( ) erreurs, telles que l’appel d’une fonction qui n’existe pas. Y a-t-il une autre façon d’attraper ces erreurs ?

Je suis en train d’appeler `` pour toutes les erreurs et suis sous PHP 5.2.3.

642voto

user259973 Points 3255

Journal des erreurs fatales à l'aide de register_shutdown_function, ce qui nécessite 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));
  }
}

Vous devrez définir l' error_mail et format_error fonctions. Par exemple:

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

L'utilisation de Swift Mailer pour écrire l' error_mail fonction.

Voir aussi:

160voto

periklis Points 4978

juste venu avec cette solution (php 5.2.0+) :

Types d’erreurs différents définis au http://www.php.net/manual/en/errorfunc.constants.php

119voto

keparo Points 13747

PHP ne sera pas vous fournir tous les moyens conventionnels pour la capture des erreurs fatales parce qu'ils vraiment ne devraient pas être pris. C'est-à-dire, vous ne devriez pas tenter de récupérer d'une erreur fatale. Chaîne de caractères correspondant à une mémoire tampon de sortie est certainement mal conseillé.

L'appel de la fonction mail() de l'intérieur d'un gestionnaire d'erreurs de méthode s'avérer problématique, trop. Si vous avez eu beaucoup d'erreurs, votre serveur de messagerie serait chargé, avec le travail, et vous pourriez vous retrouver avec une gnarly boîte de réception. Pour éviter cela, vous pouvez envisager de faire tourner un cron pour analyser les journaux d'erreur périodique et envoyer des notifications en conséquence. Vous pouvez aussi rechercher dans le système logiciel de surveillance, tels que Nagios.


Pour parler du bit sur l'enregistrement d'une fonction d'arrêt:

Il est vrai que vous pouvez vous inscrire à un arrêt de la fonction, et c'est une bonne réponse.

Le point ici est que vous ne devriez pas tenter de récupérer à partir des erreurs fatales, surtout pas en utilisant une expression régulière à l'encontre de votre tampon de sortie. Je répond à la accepté de répondre, qui était liée à une suggestion sur php.net qui a depuis été modifiés ou supprimés.

Cette suggestion a été d'utiliser une regex par rapport à la sortie de la mémoire tampon lors de la manipulation d'exception, et dans le cas d'une erreur fatale (détecté par la correspondance contre quel que soit configuré texte d'erreur que vous pourriez attendre de), essayer de faire une sorte de reprise ou de la poursuite de la procédure. Ce ne serait pas une pratique recommandée (je crois que c'est pourquoi je ne peux pas trouver l'origine de la suggestion, trop. Je suis en train de donnant sur, ou à la communauté php abattu).

Il pourrait être intéressant de noter que les versions les plus récentes de PHP (environ 5.1) semblent appeler la fonction d'arrêt plus tôt, avant que le tampon de sortie de rappel est envoked. Dans la version 5 et les versions antérieures, que l'ordre était l'inverse (le tampon de sortie de rappel a été suivie par la fonction d'arrêt). Aussi, depuis près de 5.0.5 (qui est beaucoup plus tôt que l'interlocuteur de la version 5.2.3), les objets sont déchargés bien avant un régime enregistré d'arrêt de la fonction est appelée, donc vous ne serez pas en mesure de compter sur vos objets en mémoire à faire beaucoup de chose.

Si l'enregistrement d'une fonction d'arrêt est très bien, mais le genre de tâches qui devraient être effectuées par une fonction d'arrêt sont probablement limités à une poignée de doux arrêt des procédures.

La clé à emporter voici quelques mots de sagesse pour ceux qui bute sur cette question et voit les conseils dans le initialement accepté de répondre. Ne pas regex votre tampon de sortie.

38voto

sakhunzai Points 2399

Eh bien, il semble possible d’intercepter les erreurs fatales d’autres passant  :)

25voto

Lucas Batistussi Points 513

J'ai développé une façon d'attraper tous les types d'erreur en PHP (presque tous)! Je n'ai pas sûr de E_CORE_ERROR ( je pense ne fonctionne uniquement pour que l'erreur)! Mais, pour d'autres erreurs fatales (E_ERROR, E_PARSE, E_COMPILE...) fonctionne à l'aide d'une seule fonction du gestionnaire d'erreurs! Il y va de ma solution:

Placez le code suivant dans votre fichier principal (index.php):

<?php

define('E_FATAL',  E_ERROR | E_USER_ERROR | E_PARSE | E_CORE_ERROR | 
        E_COMPILE_ERROR | E_RECOVERABLE_ERROR);

define('ENV', 'dev');

//Custom error handling vars
define('DISPLAY_ERRORS', TRUE);
define('ERROR_REPORTING', E_ALL | E_STRICT);
define('LOG_ERRORS', TRUE);

register_shutdown_function('shut');

set_error_handler('handler');

//Function to catch no user error handler function errors...
function shut(){

    $error = error_get_last();

    if($error && ($error['type'] & E_FATAL)){
        handler($error['type'], $error['message'], $error['file'], $error['line']);
    }

}

function handler( $errno, $errstr, $errfile, $errline ) {

    switch ($errno){

        case E_ERROR: // 1 //
            $typestr = 'E_ERROR'; break;
        case E_WARNING: // 2 //
            $typestr = 'E_WARNING'; break;
        case E_PARSE: // 4 //
            $typestr = 'E_PARSE'; break;
        case E_NOTICE: // 8 //
            $typestr = 'E_NOTICE'; break;
        case E_CORE_ERROR: // 16 //
            $typestr = 'E_CORE_ERROR'; break;
        case E_CORE_WARNING: // 32 //
            $typestr = 'E_CORE_WARNING'; break;
        case E_COMPILE_ERROR: // 64 //
            $typestr = 'E_COMPILE_ERROR'; break;
        case E_CORE_WARNING: // 128 //
            $typestr = 'E_COMPILE_WARNING'; break;
        case E_USER_ERROR: // 256 //
            $typestr = 'E_USER_ERROR'; break;
        case E_USER_WARNING: // 512 //
            $typestr = 'E_USER_WARNING'; break;
        case E_USER_NOTICE: // 1024 //
            $typestr = 'E_USER_NOTICE'; break;
        case E_STRICT: // 2048 //
            $typestr = 'E_STRICT'; break;
        case E_RECOVERABLE_ERROR: // 4096 //
            $typestr = 'E_RECOVERABLE_ERROR'; break;
        case E_DEPRECATED: // 8192 //
            $typestr = 'E_DEPRECATED'; break;
        case E_USER_DEPRECATED: // 16384 //
            $typestr = 'E_USER_DEPRECATED'; break;

    }

    $message = '<b>'.$typestr.': </b>'.$errstr.' in <b>'.$errfile.'</b> on line <b>'.$errline.'</b><br/>';

    if(($errno & E_FATAL) && ENV === 'production'){

        header('Location: 500.html');
        header('Status: 500 Internal Server Error');

    }

    if(!($errno & ERROR_REPORTING))
        return;

    if(DISPLAY_ERRORS)
        printf('%s', $message);

    //Logging error on php file error log...
    if(LOG_ERRORS)
        error_log(strip_tags($message), 0);

}

ob_start();

@include 'content.php';

ob_end_flush();

?>

J'espère que cela aide beaucoup de gens! J'étais à la recherche de cette solution trop longtemps et ne pas trouver! Ensuite, j'ai développé un!

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X