Page 1 sur 1

L'avantage de set_exception_handler().

Posté : 03 mars 2012, 15:23
par djun
Bonjour,

J'apprends les exception. Mais, il y a une partie dans le tuto que je comprends pas. Il dit que catch(){} et try{} ne capture pas les éléments et il sont perdu a jamais. J'ai pas trop compris.

Re: L'avantage de set_exception_handler().

Posté : 03 mars 2012, 15:36
par Ryle
Je ne comprends absolument pas ta question, mais voici ce qui la documentation :

set_exception_handler() définit le gestionnaire d'exceptions par défaut. La fonction spécifiée sera appelée si une exception est déclenchée et que celle-ci n'est pas gérée par un bloc try/catch.
<?php
function exception_handler($exception) {
  echo "Exception non attrapée : " , $exception->getMessage(), "\n";
}

set_exception_handler('exception_handler');

throw new Exception('Uncaught Exception');
echo "Non exécuté\n";
?>
Pour le reste, www.php.net ! :)

Re: L'avantage de set_exception_handler().

Posté : 03 mars 2012, 16:20
par djun
Je ne comprends absolument pas ta question, mais voici ce qui la documentation :

set_exception_handler() définit le gestionnaire d'exceptions par défaut. La fonction spécifiée sera appelée si une exception est déclenchée et que celle-ci n'est pas gérée par un bloc try/catch.
<?php
function exception_handler($exception) {
  echo "Exception non attrapée : " , $exception->getMessage(), "\n";
}

set_exception_handler('exception_handler');

throw new Exception('Uncaught Exception');
echo "Non exécuté\n";
?>
Pour le reste, http://www.php.net ! :)
C'est quoi l'avantage de set_exception_handler() sur try{} et catch(){}?

Re: L'avantage de set_exception_handler().

Posté : 03 mars 2012, 17:36
par xTG
Son avantage est que au lieu de devoir sur un quelconque code devoir mettre 6 try..catch (pour je ne sais quelle raison) tu as juste à définir cet handler qui ferra le même travail.

Re: L'avantage de set_exception_handler().

Posté : 04 mars 2012, 14:15
par djun
merci

Re: L'avantage de set_exception_handler().

Posté : 23 mai 2012, 15:33
par vidda
Bonjour,

Je me permet de rebondir sur le sujet.

Je crée en ce moment même un gestionnaire d'erreur ET un gestionnaire d'exception en POO.

Pour le gestionnaire d'erreur ça va très bien. J'ai même fait en sorte qu'une erreur interne du gestionnaire d'erreur renvoie une exception pour éviter une boucle infinie.
Ce même gestionnaire d'erreur me sert pour logger les erreur PDO qui sont spécifiques à un traitement particulier.

Or, je m'aperçoit que mon gestionnaire d’événements, qui pourtant étend la classe Exception, ne peuple pas son attribut $message. J'avais bien entendu un constructeur qui appelait son constructeur parent.

Du coup pour palier au probleme, j'ai ajouté une méthode à mon gestionnaire d’événement mais du coup je suis quand même obligé d'utiliser un bloc try/catch pour récupérer les "erreurs", et c'est dans ce bloc catch que j'appelle ma méthode avec pour argument le message et le code rattrapés par le catch.

voila mon gestionnaire d'exceptions:
class myException extends Exception implements Input  
{ 
  private $Outputs=array();
  private $_Error;
  function __construct($str=NULL,$code=0)
  { parent::__construct($str, intval($code));
    $this->getError();
  }
  

  function setMessage($str=NULL,$code=0)// methode pour peupler parent::message et parent::code "manuellement"
  { parent::__construct($str, intval($code));
    $this->getError();
  }

  function addOutput(Output $obj)// ajout de module de sortie
  { if(!in_array($obj,$this->Outputs)) $this->Outputs[]=$obj;
    return $this;
  }

  public function removeOutput(Output $obs)
  { if (is_int($key = array_search($obs, $this->Outputs, true))) unset($this->_Outputs[$key]);
    return $this;
  }
  
  function getError()
  { if(count($this->Outputs)==0) 
    { if(PHPDEBUG) $this->addOutput(new HtmlDisplay("div",'style="color:#C00"'));  // HtmlDisplay est une classe qui envoie l'erreur en html
	  else $this->addOutput(new UserDisplay());  // UserDisplay est une sortie qui renvoie "un probleme est survenu sans autre details"
	}
	$this->_Error=array('erreur'=>$this->getCode(),'message'=>$this->getMessage(),'fichier'=>$this->getFile(),'ligne'=>$this->getLine());
	$this->Display();
  }
  function getOutput(Output $obj)
  { try
    { if(in_array($obj,$this->Outputs)) return $this->_Error;
	}
	catch(Exception $e)
	{ $_ENV['Exception']->setMessage($e->getMessage(),$e->getCode()); 
	}
  }
  function Display()
  { foreach($this->Outputs as $Output)
    { $Output->run($this);
    }
  }
}

class testdisplay implements Output // une sortie simplette pour l'exemple
{ function run(Input $obj)
  { print_r($obj->getMessage($this)); 
  } 
}

$_ENV['exception']=new myException()
$_ENV['exception']->addOutput(new testdisplay());

set_exception_handler(array($_ENV['exception'],'getError'));
Les interfaces Input et Output servent juste à s'assurer que l'entrée de données trouve une sortie qui lui corresponde sans faute, mais ce qui m'importe n'est pas la sortie mais plutôt les entrées. La classe "testdisplay" n'est donc qu'un exemple simplifié.

à l'instanciation de l'objet $_ENV['Exception'] on se rend bien compte que rien n'est passé au constructeur. Du coup je ne m'etonne pas de ne rien y trouver.
Ce qui me gene, c'est l'ajout de "module" de sortie et l'appel à la méthode principale de l'objet "getError".
en effet, je ne peux pas ajouter de module de sortie à une classe, je dois passer par un objet déjà instancié. du coup je ne pense pas pouvoir utiliser de méthode statique pour ajouter ces modules.

pour l'instant, je suis obligé de faire comme suit:

try
{ echo $ma_variable_qui_nexiste_pas;
}
catch(Exception $e)
{ $_ENV['Exception']->addMessage($e->getMessage,$e->getCode());
}

Ça marche, mais c'est complétement ridicule. On attrape une exception pour en rebalancer une derrière. C'est comme de se payer une porsche mais de devoir la rejoindre à velo.

si je fais
set_exception_handler(array('myException','getError'));
j'obtiens un joli message d'erreur: Non-static method myException::getError() should not be called statically

Il faut aussi ajouter que ce gestionnaire d'exception ne peut pas être un singleton sachant que les exceptions venant du gestionnaire d'ERREUR et celles retournées par les erreurs PDO doivent être traitées différemment. ma classe PDO perso a un attribut publique statique étant une autre instance de myException.

Des idées? s'il vous faut d'autres précisions, je me ferai une joie d'y répondre