__autoload, et SPL.

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : __autoload, et SPL.

par Hywan » 23 juil. 2007, 16:45

Oui, c'est ce que je pensais faire :) Problème résolu donc.

par Invité » 23 juil. 2007, 16:29

Ben tu stockes la pile des exceptions quelque part, et c'est réglé :)

Un truc de ce genre :
class Autoloader {

  public static function autoload($className) {
    try {
      // ...
    } catch (Exception $e) {
      self::registerException($e);
    }
  }

  protected static $registeredExceptions = array();

  public static function registerException(Exception $e) {
    self::$registeredExceptions[] = $e;
  }

  public static function lastRegisteredException() {
    return array_pop(self::$registeredExceptions);
  }

  public static function countRegisteredExceptions() {
    return count(self::$registeredExceptions);
  }

}

spl_autoload_register(array('Autoloader', 'autoload'));
Comme ça quand une exception est levée dans le loader, il l'attrape, il la met dans une pile, et toi tu as accès à cette pile.

par Hywan » 22 juil. 2007, 12:32

Oui ok. Hmm ... c'est intéressant.
Mais ce que je voulais faire, c'était récupérer l'exception plus loin, mais apparement, ça va être difficile. Je n'ai pas le temps aujourd'hui pour programmer, mais je regarderais ça lundi.

Merci :)

par Sékiltoyai » 22 juil. 2007, 12:05

Bah c'est bien ce que je disais, si tu laisses l'exception se répandre, ca fait une fatal error, et ce, parce que __autoload() n'est pas appelé par $test = new test(); , mais par le noyau php lui même, et toute exception qui remonte au noyau provoque une erreur (essayez avec ceci par exemple) :
<?php

function except()
{
throw new Exception('test');
}

except();

?>
Normalement, vous devriez avoir une belle fatal error...

par Hywan » 22 juil. 2007, 11:18

Ce n'est pas tout à fait le même je crois.
Toi, tu lances et captures une erreur. Nous, on ne fait que la lancer pour la capturer plus loin dans le code. Du fait que tu affiches $e->getMessage(), PHP doit considérer le processus d'exception comme terminé, et donc, pas d'erreur.
Il faudrait que je retrouve cette page où il parlait du bug avec la SPL pour l'autoload ... Peut être qu'on aurait plus d'explications.

par Sékiltoyai » 22 juil. 2007, 02:28

C'est normal que moi, je n'ai pas d'erreur ?
<?php

function __autoload($class)
{

	try
	{
		throw new Exception('test');
	}
	catch(Exception $e)
	{
		echo $e->getmessage();
		include('test_class.php');
	}

}

$test = new test();

?>
(avec une classe test dans le fichier test_class.php)

Vous avez quelle version de php ?

par titerm » 22 juil. 2007, 00:19

En fait, moi j'ai mon propre gestionnaire d'exception. Il prend bien entendu en parametre une exception...

c'est qq chose du genre
function MyExceptionHandler(Exception $e) {
// mon systeme de dump 
}
et on l'enregistre via
set_exception_handler('MyExceptionHandler');

Ce qu'il est possible de faire alors dans l'autoload, c'est de simuler une exception.

Genre si je constate une erreur,

je fais un
MyExceptionHandler(new Exception("Le fichier '$final' n'est pas lisible"));
Ce qui instancie une nouvelle exeption mais ne la lance pas, et je la passe a mon exection Handler perso qui va faire mon dump perso. Au final, j'ai exactement le meme résultat visuelle mais je n'ai pas jeté d'exception.

par Hywan » 21 juil. 2007, 22:51

Titerm a raison, je t'ai mal lu.
C'est ce qui m'a rendu fou, une erreur fatale efface les echos, et donc pas moyen de voir d'où venait mon erreur car j'avais pas fais attention à la note dans la documentation.

Moi qui prone toujours le manuel, ça m'apprendra :lol:.

En définitive : surtout pas d'exceptions dans l'autoload. Capturée ou jetée, dans aucun cas. J'ai juste fais un return false; si mon fichier n'existe pas, c'est tout.

On peut quand même lancer une exception avec une évaluation du code, mais jtrouvais ça trop crade, donc je l'ai pas fais. Vous pouvez voir les commentaires.
J'ai cru comprendre que la gestion des exceptions dans l'autoload était mal conçue car c'était un bug. Le bug peut être contourné avec eval. On peut s'attendre à une mise à jours pour les prochaines versions de PHP :).

par Sékiltoyai » 21 juil. 2007, 21:26

Sékiltoyai, le morceau de doc qu'il donne dit qu'une exception emise dans l'autoload ne peut pas etre capturé dans un bloc 'catch' et que le resultat est une erreur fatal.
C'est bizarre ca alors...

par titerm » 21 juil. 2007, 19:20

Sékiltoyai, le morceau de doc qu'il donne dit qu'une exception emise dans l'autoload ne peut pas etre capturé dans un bloc 'catch' et que le resultat est une erreur fatal.

par Hywan » 21 juil. 2007, 17:37

Oui, je devais être fatigué ... C'est surtout le fait qu'il m'affichait pas mon echo qui m'a conduit en erreur.

par Sékiltoyai » 21 juil. 2007, 17:12

Note : Exceptions thrown in __autoload function cannot be caught in the catch block and results in a fatal error.
J'avais compris que si une exception était lancée, on aurait une erreur fatale. Oui c'est le cas. Mais je pensais pas que le simple fait d'invoquer l'exception aurait le même comportement.
Bah il n'y a aucune différence entre lancer une exception et ne pas la capturer. Le résultat est le même, elle va continuer à se répandre.
Mais si tu mets un try dans ta fonction, tu pourras la capturer.

par Hywan » 21 juil. 2007, 16:10

J'ai enfin trouvé mon problème.
Note : Exceptions thrown in __autoload function cannot be caught in the catch block and results in a fatal error.
J'avais compris que si une exception était lancée, on aurait une erreur fatale. Oui c'est le cas. Mais je pensais pas que le simple fait d'invoquer l'exception aurait le même comportement.

J'avais donc chercher autre chose, et je me suis méchament emmêler les pinceaux. Mais c'est bon, tout marche bien navette ;-)

Edit : Au passage, je me suis pris la tête car si une exception est lancée dans l'autoload, même les echo lancés avant l'exception ne sont pas affichés ...

par titerm » 21 juil. 2007, 13:39

bah si ton autoload est reconnu (fait un echo $class dedans) tu verras ce qu'il essai de charger

Après, il faut que tu soit strict dans tes regles de nommage de fichier.
Moi j'utilise l'autoload de la spl, j'ai plusieurs procédures d'autoload, 2 persos plus celle du zend framework. j'ai plusieurs centaines de classe et aucun pb.

par Hywan » 21 juil. 2007, 13:30

Bah justement, j'ai l'impression qu'il ne reconnait pas mon __autoload ...
Je me replonge dans le problème aujourd'hui, je vous en dirais plus :)