Question

Je connais quelques notions de base, mais j'aimerais en savoir plus sur le moment et la raison pour laquelle la gestion des erreurs (y compris les exceptions de projection) devrait être utilisée en PHP, en particulier sur un site actif ou une application Web. Est-ce quelque chose qui peut être surutilisé et si oui, à quoi ressemble la surutilisation? Y a-t-il des cas où il ne devrait pas être utilisé? En outre, quelles sont certaines des préoccupations de sécurité communes en ce qui concerne le traitement des erreurs?

Était-ce utile?

La solution

Une chose à ajouter à ce qui a déjà été dit est qu’il est primordial que vous enregistriez les erreurs de votre application Web dans un journal. De cette façon, comme Jeff "Coding Horror" Atwood suggère, vous saurez quand vos utilisateurs rencontrent des problèmes avec votre application (au lieu de "leur demander ce qui ne va pas").

Pour ce faire, je recommande le type d'infrastructure suivant:

  • Créer un " crash " table dans votre base de données et un ensemble de classes wrapper pour signaler les erreurs. Je recommanderais de définir des catégories pour les blocages ("blocage", "sécurité", "erreur / avertissement PHP" (par opposition à une exception), etc.).
  • Dans tous vos codes de traitement des erreurs, assurez-vous de les enregistrer. Cela dépend systématiquement de la qualité de la construction de l'API (étape ci-dessus) - il devrait être trivial d'enregistrer les plantages si cela est correctement effectué.

Crédits supplémentaires: parfois, vos collisions seront des collisions au niveau de la base de données: serveur DB, etc. Si tel est le cas, votre infrastructure de journalisation des erreurs (ci-dessus) échouera (vous ne pouvez pas vous connecter à la base de données, car le journal tente d’écrire dans la base de données). Dans ce cas, j’écrirais la logique de basculement de votre classe wrapper Crash dans

  • envoyer un email à l'administrateur, ET / OU
  • enregistrer les détails de l'incident dans un fichier texte brut

Tout cela semble exagéré, mais croyez-moi, cela changera le point de savoir si votre candidature est acceptée comme "stable". ou "feuilleté". Cette différence provient du fait que toutes les applications commencent à être saccadées / effondrées, mais les développeurs qui connaissent tous les problèmes liés à leur application ont la possibilité de résoudre le problème.

Autres conseils

En gros, les erreurs sont héritées de PHP, alors que les exceptions sont le moyen moderne de les traiter. Le plus simple est donc de configurer un gestionnaire d’erreur qui lève une exception. De cette façon, toutes les erreurs sont converties en exceptions, et vous pouvez alors simplement gérer un schéma de traitement des erreurs. Le code suivant convertira les erreurs en exceptions pour vous:

function exceptions_error_handler($severity, $message, $filename, $lineno) {
  if (error_reporting() == 0) {
    return;
  }
  if (error_reporting() & $severity) {
    throw new ErrorException($message, 0, $severity, $filename, $lineno);
  }
}
set_error_handler('exceptions_error_handler');
error_reporting(E_ALL ^ E_STRICT);

Il existe cependant quelques cas où le code est spécifiquement conçu pour fonctionner avec des erreurs. Par exemple, la méthode schemaValidate de DomDocument déclenche des avertissements lors de la validation d'un document. Si vous convertissez les erreurs en exceptions, la validation cessera après le premier échec. Parfois, c'est ce que vous voulez, mais lors de la validation d'un document, vous voudrez peut-être tous des échecs. Dans ce cas, vous pouvez installer temporairement un gestionnaire d’erreurs, qui collecte les erreurs. Voici un petit extrait que j'ai utilisé à cette fin:

class errorhandler_LoggingCaller {
  protected $errors = array();
  function call($callback, $arguments = array()) {
    set_error_handler(array($this, "onError"));
    $orig_error_reporting = error_reporting(E_ALL);
    try {
      $result = call_user_func_array($callback, $arguments);
    } catch (Exception $ex) {
      restore_error_handler();
      error_reporting($orig_error_reporting);
      throw $ex;
    }
    restore_error_handler();
    error_reporting($orig_error_reporting);
    return $result;
  }
  function onError($severity, $message, $file = null, $line = null) {
    $this->errors[] = $message;
  }
  function getErrors() {
    return $this->errors;
  }
  function hasErrors() {
    return count($this->errors) > 0;
  }
}

Et un cas d'utilisation:

$doc = new DomDocument();
$doc->load($xml_filename);
$validation = new errorhandler_LoggingCaller();
$validation->call(
  array($doc, 'schemaValidate'),
  array($xsd_filename));
if ($validation->hasErrors()) {
  var_dump($validation->getErrors());
}

Les erreurs non gérées arrêtent le script. C’est une bonne raison de les gérer.

En général, vous pouvez utiliser un bloc Try-Catch pour traiter les erreurs

try
{
    // Code that may error
}
catch (Exception $e)
{
    // Do other stuff if there's an error
}

Si vous souhaitez arrêter le message d'erreur ou d'avertissement qui apparaît sur la page, vous pouvez préfixer l'appel avec un signe @, comme suit.

 @mysql_query($query);

Avec les requêtes, c’est généralement une bonne idée de faire quelque chose comme ça pour avoir une meilleure idée de ce qui se passe.

@mysql_query($query)
    or die('Invalid query: ' . mysql_error() . '<br />Line: ' . __LINE__ . '<br />File: ' . __FILE__ . '<br /><br />');

Vous devez utiliser la gestion des erreurs dans les cas où vous n’avez pas le contrôle explicite des données sur lesquelles votre script fonctionne. J'ai tendance à l'utiliser fréquemment, par exemple dans des endroits tels que la validation de formulaire. Il est un peu pratique de savoir comment repérer des zones sujettes aux erreurs dans le code: elles sont généralement utilisées après les appels de fonction qui renvoient une valeur ou lors du traitement des résultats d'une requête de base de données. Vous ne devriez jamais présumer que le retour d'une fonction correspondra à vos attentes, et vous devez être sûr de coder par anticipation. Vous n'avez pas à utiliser les blocs try / catch, bien qu'ils soient utiles. Souvent, vous pouvez vous en tirer avec un simple contrôle if / else.

La gestion des erreurs va de pair avec les pratiques de codage sécurisé, car il existe de nombreuses "erreurs". cela ne provoque pas simplement votre script à planter. addedbytes a une bonne série de 4 articles sur quelques notions de base de la programmation sécurisée en PHP que vous pouvez trouver ICI . Il y a beaucoup d'autres questions ici sur stackoverflow sur des sujets tels que mysql_real_escape_string et Expressions régulières qui peuvent s'avérer très puissants pour confirmer le contenu de données entrées par l'utilisateur.

La meilleure pratique à mon humble avis consiste à utiliser l’approche suivante: 1. créer un gestionnaire d’erreur / exception 2. démarrer au démarrage de l'application 3. Traitez toutes vos erreurs de l'intérieur

<?php

classe Debug {

    public static setAsErrorHandler() {
         set_error_handler(array(__CLASS__, '__error_handler'));
    }

public static function __error_handler($errcode, $errmsg, $errfile, $errline) {
       if (IN DEV) {
                print on screen
           }
           else if (IN PRO) {
                log and mail
           } 
    }

}

Debug :: setAsErrorHandler ();

? >

Plutôt que de sortir mysql_error, vous pouvez le stocker dans un journal. De cette façon, vous pouvez suivre l'erreur (et vous ne dépendez pas des utilisateurs pour la signaler) et vous pouvez y aller et supprimer le problème.

Le meilleur traitement des erreurs est celui qui est transparent pour l'utilisateur. Laissez votre code résoudre le problème, inutile d'impliquer cet utilisateur.

En plus de gérer immédiatement les erreurs dans votre code, vous pouvez également utiliser

http://us.php.net/manual /en/function.set-exception-handler.php
et
http://us.php.net/manual/en/ function.set-error-handler.php

Je trouve particulièrement utile de définir votre propre gestionnaire d'exceptions. Lorsqu'une exception se produit, vous pouvez effectuer différentes opérations en fonction de son type.

ex: lorsqu'un appel mysql_connet renvoie FALSE , je jette une nouvelle exception DBConnection (mysql_error ()) et le traite avec un paramètre "spécial". manière: enregistrez l'erreur, les informations de connexion à la base de données (hôte, nom d'utilisateur, mot de passe), etc.

Je l'utilise pour compléter la gestion des erreurs standard. Je ne recommanderais pas de trop utiliser cette approche

La suppression d'erreur avec @ est très lente.

Vous pouvez également utiliser Google Forms pour capturer et analyser les exceptions, sans avoir à gérer une base de données ou un serveur accessible au public. Il existe un didacticiel ici qui explique le processus.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top