web-dev-qa-db-fra.com

Meilleur moyen de gérer les erreurs sur une page php?

À l'heure actuelle, mes pages ressemblent à ceci:

if($_GET['something'] == 'somevalue')
{
    $output .= 'somecode';

    // make a DB query, fetch a row
    //...
    $row = $stmt->Fetch(PDO::ASSOC);

    if($row != null)
    {
        $output .= 'morecode';

        if(somethingIsOK())
        {
            $output .= 'yet more page output';
        }
        else
        {
            $error = 'something is most definitely not OK.';
        }
    }
    else
    {
        $error = 'the row does not exist.';
    }
}
else
{
    $error = 'something is not a valid value';
}

if($error == '') // no error
{
    //display $output on page
}
else // an error
{
    // display whatever error occurred on the page
}

La façon dont je fais les choses fonctionne, mais c'est très lourd et fastidieux pour ce qui est probablement évident: supposez que j'appelle une fonction quelque part au milieu de mon code, ou que je veuille vérifier la valeur d'une variable ou vérifier une requête de base de données a renvoyé un résultat valide, et si cela échoue, je souhaite générer une erreur? Je devrais faire un autre si/else bloquer et déplacer tout le code à l'intérieur du nouveau bloc if. Cela ne semble pas être une façon intelligente de faire les choses.

Je lisais à propos de try/catch et je pensais mettre tout mon code dans une instruction try, puis je le laissais s'exécuter de manière séquentielle sans aucun bloc if/else et si quelque chose échouait, lançait une exception. D'après ce que j'ai lu, cela interromprait l'exécution et le ferait passer directement au bloc catch (tout comme une instruction échouée si irait au bloc else), où je pourrais alors générer le message d'erreur. Mais est-ce une pratique acceptable ou standard?

Quel est le meilleur moyen de gérer les erreurs, fatales ou non, dans une application php qui construit et affiche une page HTML? Je ne veux pas simplement mourir avec un écran vide, ce qui ne plairait pas beaucoup à l'utilisateur, mais je veux plutôt afficher un message dans le corps de la page, tout en permettant à l'en-tête et au pied de page de s'afficher.

Merci pour vos conseils! 

35
Nate

PHP a une classe intégrée, ErrorException , pour traduire PHP erreurs en exceptions, qui, si elles n'étaient pas gérées, arrêteraient naturellement l'exécution. 

Les exceptions ont amélioré les mécanismes de gestion des erreurs (try catch) et les informations de débogage (traces de pile).

Incluez ceci en haut de votre chemin d'exécution (la config, ou quelque chose qui est inclus en premier avec tout votre code):

 set_error_handler(function($nNumber, $strMessage, $strFilePath, $nLineNumber){
      throw new \ErrorException($strMessage, 0, $nNumber, $strFilePath, $nLineNumber);
 }, /*E_ALL*/ -1);

Bien que PDO prenne en charge le lancement d’exceptions, il est désactivé par défaut, vous devez l’activer:

 $pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);

Si vous utilisez MySQL, vous souhaitez également une erreur pour ne pas définir les champs obligatoires et de nombreuses autres erreurs/avertissements pardonnés:

 $pdo->exec("SET sql_mode = 'STRICT_ALL_TABLES'");

Les exceptions peuvent être gérées comme dans beaucoup d'autres langages de programmation en utilisant try catch finally :

try
{
    echo $iAmAnUndefinedVariable;
}
catch(\Throwable $exception)
{
    /*[...]*/
}

Lors de la validation des commandes, lancez simplement des exceptions: throw new Exception("Missing URL variable userId!");

Ce serait bien si PHP opérait un jour une nouvelle étape dans les héritages error report thing et lançait des exceptions par défaut (déconseiller error_reporting () et changer le comportement par défaut).

6
Tiberiu-Ionuț Stan

C'est beaucoup plus élégant et lisible.

try
{

    if($_GET['something'] != 'somevalue') 
    {
        throw new Exception ('something is not a valid value');
    }


    $output .= 'somecode';

    // make a DB query, fetch a row
    //...
    $row = $stmt->Fetch(PDO::ASSOC);

    if($row == null)
    {
        throw new Exception ('the row does not exist.');
    }


    $output .= 'morecode';


    if(somethingIsOK())
    {
        $output .= 'yet more page output';
    }
    else
    {
        throw new Exception ('something is most definitely not OK.');
    }


    echo $output;

}
catch (Exception $e)
{
    echo $e->getMessage();
}
5
Edson Medina

Utiliser try-catch est l’une des solutions les plus propres que vous puissiez utiliser.

J'ai créé un exemple qui affiche toujours l'en-tête et le pied de page lorsqu'une erreur se produit, en utilisant votre code converti au format try-catch:

PHP:

<?php
try {
    $output = array();
    if($_GET['something'] != 'somevalue') throw new Exception('something does not have a valid value.');
    $output[] = 'Some Code';
    $row = mt_Rand(0, 10) < 5 ? null : mt_Rand(0, 100);
    if($row === null) throw new Exception('The row does not exist.');
    $output[] = $row;
    if(!somethingIsOK()) throw new Exception('Something is most definitely not OK.');
    $output[] = 'Yet more page output';
} catch(Exception $e) {
    $output[] = 'Error: ' . $e->getMessage(); // To show output and error
    $output = array('Error: ' . $e->getMessage()); // To only show error
}
function somethingIsOK() {
    return mt_Rand(0, 10) < 5;
}
?>

HTML:

<!DOCTYPE HTML>
<html lang="en-US">
<head>
    <meta charset="UTF-8" />
    <title>PHP Error test</title>
    <style type="text/css">
body {
    background: #eee;
    text-align: center
}
#content {
    padding: 60px
}
#header {
    padding: 30px;
    background: #fff
}
#footer {
    padding: 10px;
    background: #ddd
}
    </style>
</head>
<body>
    <div id="header">Header</div>
    <div id="content">
<?php echo implode('<br />', $output); ?>

    </div>
    <div id="footer">Footer</div>
</body>
</html>

Références:

2
uınbɐɥs

La gestion des exceptions d’erreurs PDO pour les requêtes, et en réalité tout le code doit être exécuté:

try{

}

catch{


}

finally{

}

La raison en est que le débogage est beaucoup plus facile lorsque vous pouvez localiser à peu près l'endroit où une longue erreur se produit.

plus d'infos ici: http://php.net/manual/en/language.exceptions.php

1
CodeTalk

Créez un gestionnaire d'erreurs (set_error_handler) et envoyez-lui des exceptions.
Cela aidera pour les fonctions qui ne supportent pas les exceptions.

0
DmitryR

Gérez correctement les erreurs et les avertissements PHP à l'aide des fonctions de gestion des erreurs. (Voir exemple ici )

Le meilleur moyen de gérer les erreurs dans PHP est, Vous pouvez arrêter tous les rapports d’erreurs en ajoutant cette ligne en haut de votre fichier php -

error_reporting(0);

//OR

error_reporting('E_ALL');

// Predefined Constant

Traitement des erreurs dans PHP à l'aide des fonctions:

  • debug_backtrace - Génère une trace
  • debug_print_backtrace - Imprime une trace
  • error_clear_last - Efface la dernière erreur
  • error_get_last - Lit la dernière erreur survenue
  • error_log - Envoie un message d'erreur à la routine de traitement d'erreur définie
  • error_reporting - Définit les erreurs PHP à signaler
  • restore_error_handler - Restaure la fonction précédente du gestionnaire d'erreurs
  • restore_exception_handler - Restaure la fonction de gestionnaire d'exception précédemment définie
  • set_error_handler - Définit une fonction de gestion des erreurs définie par l'utilisateur
  • set_exception_handler - Définit un gestionnaire d'exceptions défini par l'utilisateur function
  • trigger_error - Génère un message d'erreur/avertissement/avis au niveau utilisateur
  • user_error - Alias ​​de trigger_error

Toutes les fonctions listées ci-dessus sont utilisées pour la gestion des erreurs en PHP.

0
Steve