ErrorHandler - comment gérer les erreurs

Besoins

Lorsque l'on construit un projet web et que l'on déploi, il arrive parfois des erreurs (un fichier déplacé, une variable supprimée ...)

Cependant en PHP ce type d'erreur peut être fatale en terme de communication par rapport aux utilisateurs. Nous allons donc créer un objet, une classe qui va nous permettre de gérer ces erreurs proprements.

les interfaces

Pour créer cet objet, on va utiliser le design pattern observers. Nous l'avons déjà utilisé pour le mailEventListener donc pas la peine de développer d'avantage

  1. On défini le sujet

    il faudra obligatoire ajouter et retirer les observers et les déclencher

    • interface Isubject{
      • public function attach($obs);
      • public function detach($obs);
      • public function notifyObs();
    • }
  2. On défini l'observer

    l'observer doit simplement faire les mise à jour en fonction du sujet observé

    • interface Iobserver{
      • public function update($obj);
    • }

créer la classe ErrorHandler

Allez on passe aux choses sérieuses on va créer notre classe sujet : ErrorHandler

Pour le moment on va se contenter des fonctions obligatoires.

  • class ErrorHandler implements Isubjet{
    • private $_obs;//tableau pour stocker les observers
    • public function __construct(){
      • $this->_obs=[];
      }
    • public function attach($obs){
      • $this->_obs[]=$obs;
      }
    • public function detach($obs){
      • if(is_int($key=array_search($obs,$this->_obs,true)))
        • unset($this->_obs[$key];
      }
    • public function notifyObs(){
      • foreach($this->_obs as $observer){
        • $observer->update($this);
      • }
      }
  • }

laissons cette classe pour le moment, on l'adaptera plus tard

l'observer

A présent que l'on a un début de sujet, on va créer un observer. Celui-ci se contentera de mettre à jour un fichier d'erreur (log)

  • class LogFile implements Iobserver{
    • private $file;//fichier de log
    • public function __construct($file){
      • $this->file=$file;
    • }
    • public function update($obj){
      • $this->writeError($object->getError());
    • }
    • private function writeError($err){
      • if(file_exists($this->file)){
        • $content=file_get_contents($this->file);
      • }else{
        • $content="";
      • }
    • }
  • }

Laissons notre LogFile de coté pour le moment.

récuperer et utiliser l'erreur

On utilise une fonction privée writeError pour ecrire dans notre fichier et qui prend en paramètre l'erreur en question. Donc il faut méthode getError() dans notre classe errorHandler.

Celle-ci va retourner l'erreur donc on va avoir besoin d'une variable pour la stocker du type stdClass donc un objet à la volée.

  • class ErrorHandler implements Isubjet{
    • private $current;
    • private $_obs;//tableau pour stocker les observers
    • public function __construct(){
      • $this->_obs=[];
      • $this->current=new stdClass();
      }
    • [...]
    • public function getError(){
      • return $this->current;
    • }
    • [...]
  • }

Profitons pour ré implémenter la méthode notifyObserver() de notre classe pour prévenir les problèmes et créer la méthode pour mettre à jour la variable $current; et obtenir la ligne de code concerné le fichier et le message

  • public function notifyObs(){
    • foreach($this->_obs as $observer){
      • try{
        • $observer->update($this);
      • }cacth(\Exception $e){
        • die($e->getMessage();
    • }
  • }
  • public function error($errno,$errstr,$errfile,$errline){
    • $this->current->errorString=$errstr;
    • $this->current->errorFile=$errfile;
    • $this->current->errorLine=$errline;
    • $this->notifyObserver();
    • exit(1);
  • }

Test de l'erreur

Maintenant que l'on a nos classes prêtes, on va faire un test. Pour ce faire, on va créer une fonction qui instancie l'ErrorHandler au tout début de la page. Celle-ci devra obligatoirement utiliser la méthode set_error_handler qui va remplacer l'affichage des erreur pour notre objet

  • require_once "./errorhandler.class.php";
  • function CreateErrorHandler(){
    • $error = new ErrorHandler;
    • $error->attach(new LogFile("error.txt"));
    • $error->attach(new Message());
    • $error->attach(new Notifier());
    • set_error_handler( array( $error, 'error' ) );
  • }
  • CreateErrorHandler();
  • echo $b;