De plus, PHP étant un langage de merde ce qu'il est, je n'avais aucune information à propos de la classe concernée, aucun nom, rien, nada, le vide.
J'ai donc commencé mes investigations à l'aide du seul élément fiable en ma possession, à savoir l'appel à unserialize()
.
Une rapide recherche parmi l'intégralité de mon code m'a permis de découvrir que ma mémoire me faisait défaut et que j'utilisais bien sans m'en souvenir cette fameuse fonction.
En effet, mes tests unitaires s'éxécutent dans des processus séparés afin de garantir l'isolation des tests.
A la fin de chaque méthode de test, je met dans un segment de mémoire partagé le résultat, que je récupére ensuite dans le processus principal gérant les tests.
Or, pour stocker des données dans un segment de mémoire partagé, il faut les <q>serializer</q> à l'aide de la fonction serialize()
, et donc les deserializer
grâce à unserialize()
.
Cependant, cela n'expliquait pas pourquoi la classe de l'objet que je voulais deserializer
n'existait pas au niveau de mon processus principal.
J'ai donc récupéré le contenu du segment de mémoire partagé, j'y ai cherché la classe qui pouvait poser problème, et j'ai trouvé une classe mocké
, c'est à dire une classe générée dynamiquement dans un processus dépendant du processus principal, et que ce dernier ne pouvait donc pas connaître du fait de l'isolation des tests.
La solution ? Sauvegarder sur le système de fichier le code source de la classe mockée
au lieu de faire uniquement un appel à eval()
, afin que le processus principal puisse reconstruire les objects correspondant à ces classes.
Et la morale ? Il faut toujours avoir conscience des mécanismes sous-jacent du code que l'on conçoit, sous peine de ne pas comprendre rapidement l'origine des problèmes rencontrés et de se taper la tête au mur en accusant, pour une fois injustement, PHP d'être un langage de merde.
2 réactions
1 De kewak - 05/06/2009, 00:42
Ce n'est pas PHP qui est en cause mais plutôt le développeur, c'est le même principe dans tout les languages objet. Tu devrais savoir que la fonction eval() est à éviter.
2 De mageekguy - 05/06/2009, 06:58
@kewak :
De un, je n'ai jamais dis que j'étais exempte de tout reproche, c'est même la conclusion de mon billet.
De deux, je suis bien conscient qu'
eval()
est loin d'être la panacé.Cependant, le premier reproche fait à
eval()
vient du fait qu'il ouvre une brêche de sécurité, le second étant un problème de performance.Or, dans le cas qui nous occupe, la sécurité n'est pas un problème car
eval()
éxécute du code que j'ai généré à partir du code que j'ai écris, lui même extrait d'un fichier sur le système de fichier.Il n'y a donc aucun risque d'éxécution d'un code extérieur et l'utilisation d'
eval()
est donc justifiée puisque je maîtrise totalement le code.Quand au problème de performance, j'avoue ne pas avoir remarqué de différence, alors que le code est
à chaque éxécution, bien avant queeval()
soit utilisé.Enfin, il n'y a que deux solutions pour générer dynamiquement du code avec PHP :
eval()
, et l'écriture du code concerné sur le système de fichier et une inclusion via uninclude
.A l'époque, pour des raisons de rapidité de développement, j'avais choisi la première, et ce fut un mauvais choix dans le sens où la solution que j'ai retenu ne me permet de faire ce dont j'ai besoin aujourd'hui.
Il y a apparament un mouvement contre
eval()
assez fort, qui s'appuie sur l'argument générique , sans vraiment savoir pourquoi...