JeuWeb - Crée ton jeu par navigateur
PHP : Les exceptions - Version imprimable

+- JeuWeb - Crée ton jeu par navigateur (https://jeuweb.org)
+-- Forum : Discussions, Aide, Ressources... (https://jeuweb.org/forumdisplay.php?fid=38)
+--- Forum : Programmation, infrastructure (https://jeuweb.org/forumdisplay.php?fid=51)
+--- Sujet : PHP : Les exceptions (/showthread.php?tid=7325)

Pages : 1 2


PHP : Les exceptions - Max72 - 01-03-2015

Bonjour.

J'aurai aimé savoir si vous utilisiez les exceptions dans PHP..

En effet elles sont un moyen d'afficher les erreurs attrapées (ou pas), mais j'aime vraiment pas comment elles doivent être mises en place (try, catch, maintenant finally).

En fait, je me pose la question de : Développer une classe qui gère mes erreurs et qui, selon le type d'erreur, continue le script ou pas, ou rester sur une utilisation des exceptions qui est lourde (franchement, mettre des blocs try / catch alors qu'une condition suffit...).

J'imagine déjà la réponse, mais sait-on jamais Smile

Merci.


RE: PHP : Les exceptions - niahoo - 01-03-2015

Sinon il y a le tricot hein Smile

Toutes les librairies que tu va utiliser lèveront des exceptions, donc tu n'as pas d'autre choix que de les utiliser. Sauf si tu re-développes tous les composants de ton appli bien entendu.


RE: PHP : Les exceptions - Sephi-Chan - 01-03-2015

Les exceptions, c'est aussi de la documentation implicite (qui a l'avantage de rester à jour, elle…).

Pour moi , les exceptions sont également un moyen d'éviter la programmation défensive en blindant le code de conditions. Ainsi, mon code métier ne fait pas ou peu de vérification sur ce qu'il reçoit : c'est au code appelant d'envoyer les bonnes choses. Ça permet de garder un code clair et focalisé sur un rôle propre ; les conditions ayant tendance à proliférer. En revanche, si quelque chose se passe mal, je veux que mon code explose vite (Fail fast), pour prendre (ou non) des mesures.

Avec des exceptions dédiés (souvent je sous-classe juste StandardError) qui portent un nom sans ambiguité (GameAlreadyStarted, CharacterAlreadyDead, …) je sais tout de suite ce qui se passe (aussi bien sur le moment que quand je lis mes logs) et je peux catcher cette erreur seulement au plus au point si ça me chante (les fameux messages de type "L'application a rencontré une erreur, nos équipes ont été notifiées.") ou bien la prendre en charge plus proche de son appel pour tenter une remédiation.

Couplé à des outils de type error catcher (comme Airbrake (service) ou Errbit (self-hosted), qui ont un client pour PHP), ça permet de documenter et de monitorer ton application sans avoir à chercher dans les logs ou attendre qu'on te remonte des erreurs (avec toutes les imprécisions que ça implique).

Donc selon moi, il faut limiter le caractère défensif du programme (qui rend le code plus complexe et donc difficile à maintenir) et le laisser planter tranquille, quitte à gérer ce plantage. On peut faire ça grâce à des exceptions bien nommées et ultra spécifiques).


RE: PHP : Les exceptions - Aedius - 01-03-2015

Tu aurais voulu que ce soit utilisé comment ?

Tu peux peut être transformé les try catch en quelque chose qui te plait mieux ? Peut être avec un trait ? ( pour garder le coté objet et ne le faire qu'une seule fois )


RE: PHP : Les exceptions - Max72 - 01-03-2015

Le problème pour moi est que, si on veut faire les choses à fond, plus de la moitié du code doit être dans des try, et je trouve pas ça génial.

Exemple bateau :
Code PHP :
<?php 
function add($a, $b) {
  if (!is_numeric($a) || !is_numeric($b)) {
    throw new Exception('Bla bla')
  }
}


try {
  add(5,6);
  add(5, 'bla');
}

catch (
Exception $e) {
// Traitement
}

Perso, un simple truc comme ça m'irait très bien :
Code PHP :
<?php 
function add($a, $b) {
  if (!is_numeric($a) || !is_numeric($b)) {
    $e = new My_Exception($niveau de l alerte(notice, warning, fatal), $message);
  }
}
add(5, 'bla');

Le niveau de l'alerte déterminerait également si le script doit continuer ou pas.
Je sais que les Exceptions font mieux que cela et donnent plus de renseignements (ligne etc), et qu'il y a des raisons pour les utiliser, mais doit-on toujours s'en remettre à elles au lieu de gérer nous même ce que nous pouvons ?


RE: PHP : Les exceptions - Xenos - 01-03-2015

Rien ne t'oblige à try/catcher partout, puisque si une exception est lancée, elle "bouillonne" (ou remonte) jusqu'au bloc try/catch de niveau le plus proche (à défaut, une erreur "uncaught exception" arrive). Donc, si tu as une trace type

{main}→Game:Confusedtart()→GameLoader::load()→GameModel::countPlayer()→add()

Alors tu peux ne try/catcher que dans la partie {main}, le reste du code n'est pas "alourdi".

Sinon, tu peux parfaitement croiser les deux, et appeler une classe d'erreur dans add() qui va ou bien lancer l'exception (ce qui revient à throw/try/catch) ou bien faire autre chose (logger cela comme un warning?).
Mais ce système peut également se faire au niveau du try/catch lui-même: le code planté envoie l'exception, le catch la récupère et la passe à une classe d'erreur, qui décide (suivant le niveau de l'exception) de laisser poursuivre le code, ou bien de relancer une autre exception.

Au fond, l'intérêt du throw est d'offrir à un code appelé un moyen différent du return d'informer le code appelant d'un plantage.
Si tu préfère que le code appelé gère l'erreur lui-même, tu peux effectivement utiliser une classe d'erreur, spécifique au code appelé ou générique: le code appelant s'en fiche de comment ça se passe dans le code appelé Wink

Note que sur des cas plus complexes, le typehinting de PHP (avec un peu de code pour transformer cela en exception évite bien des lourdeurs type if (is_a($argument, "interface")).


RE: PHP : Les exceptions - atra27 - 01-03-2015

En fait il faut gere deux cas:
soit ton code peux fail en fonctionnement normal et la tu try catch pour gérer proprement (par ex: perso dead ou mauvais login)
Soit ton code ne dois pas fail en fonctionnement normal (connection db impossiblr) et tu la tu laisse l'erreur remonter (ce qui s'affiche dans le log et via une erreur 500).

En java on sépare les deux via la distinction exception (a catcher obligatoirement).
Et RuntimeException (pas obligatoirement a catcher)
En php, il n'y a pas de distinction, aucune exception n'est obligatoire a catcher, et si on ne le fais pas, php le fais.

A rajouter aussi la possibilité de faire un try catch finally pour cleanup proprement meme en cas d'erreur.

Donc au final pas besoin de try catch obligatoirement, maisnjuste la ou on en as besoin.


RE: PHP : Les exceptions - Max72 - 01-03-2015

Je crois que je vais partir sur l'idée du 'set_error_handler' et créer mes propres classes d'erreur.

Un truc un peu comme ça :

Code PHP :
<?php 
function my_error_handler($level, $msg, $file, $line)

{
   switch($level)
   {
     case E_ERROR: throw new ErrorException ($msg, 0, $level, $file, $line);
     case E_WARNING: throw new WarningException ($msg, 0, $level, $file, $line);
     // Et les autres...
   }
}

set_error_handler('my_error_handler');

Et les classes correspondantes, qui étendent la classe ErrorException :
Code PHP :
<?php 
class WarningException extends ErrorException {

   // Ici j'y met ce que je veux..
}
// Et les autres...

En gros le but est de changer tous les messages d'erreurs en ErrorException. Puis grâce à plusieurs classes d'erreurs en fonction du niveau de l'erreur.

J'ai pas testé. Ca vous semble viable ? Merci.


RE: PHP : Les exceptions - Xenos - 01-03-2015

Y'a quelques Exceptiopns SPL prédéfinies qui peuvent aider.

C'est également sur ce genre de mécanisme que je suis parti. On doit même trouver des composants de Framwork qui font déjà cette conversion PHPError→Exception.
Faut pas hésiter aussi à passer par de l'interface si besoin. Par exemple: une Exception peut être de différents niveaux (IErrorException, IWarningException,...) , de différent type (IIOException, ILogicalException, IMathsException,...) ou sous-type (INetworkException, IFileException, IURIRequestException,...), etc... L'interface pourra aider pour ajouter plus de finesse au typage de l'exception et faire du catch sur la base du niveau (catch IWarningException $e), du type (catch IIOException $e) etc.


RE: PHP : Les exceptions - Max72 - 01-03-2015

Avec toutes tes interfaces et tes classes, tu vas réécrire les Exceptions complet non ? ^^

J'implémenterai peut-être avec des interfaces, mais n'étant pas confronté à de cas concrets je n'en vois pas pour le moment l'utilité. Mais je remarque que tu aimes interfacer tout et rien Wink

Citation :Puis grâce à plusieurs classes d'erreurs en fonction du niveau de l'erreur.
Je ne sais plus ce que j'ai voulu dire, mais il doit en manquer une bonne partie ^^