mageekblog - Mot-clé - prestashopLe blog personnel de Frédéric Hardy. Au menu, PHP, agilité, FreeBSD, cuisine et photographies.2021-12-02T08:20:54+01:00Frédéric Hardyurn:md5:26874ca5b8cd4cac8d08b0e68e64f63aDotclearRetour sur les paradoxesurn:md5:dae4bbfa480c3f74764a1ef0bdb646092009-10-14T09:31:00+02:002009-10-14T14:37:43+02:00mageekguyPHPPHPprestashop<p>Dans mon <a href="http://blog.mageekbox.net/?post/2009/10/13/Saurez-vous-trouver-les-paradoxes-contenus-dans-ce-code-PHP">précédent billet</a>, j'ai demandé à mes lecteurs de trouver les deux paradoxes contenu dans un morceau de code <a href="http://www.php.net">PHP</a> issue d'un projet open-source français qui à le vent en poupe, j'ai nommé <a href="http://www.prestashop.com">prestashop</a>.</p>
<p>J'avoue que j'ai hésité à donner le nom de ce projet, mais comme je suis le premier à dire que la critique est le meilleur moyen de faire avancer les choses, je peux difficilement faire autrement.</p>
<p>Maintenant que les choses sont claires, je vais maintenant vous dire les deux paradoxes résidant dans ce morceau de code, que <a href="http://blog.mageekbox.net/?post/2009/10/13/Saurez-vous-trouver-les-paradoxes-contenus-dans-ce-code-PHP#c162">bon nombre</a> ont également détecté.</p> <ol>
<li>Si la fonction <code><a href="http://www.php.net/manual/en/language.oop5.autoload.php">__autoload()</a></code> est appelée, c'est que la classe n'est pas définie, donc il est inutile de vérifier qu'elle n'existe pas à l'aide de <code><a href="http://www.php.net/class_exists">class_exists()</a></code>.</li>
<li>Si la classe n'existe pas, c'est que le fichier la définissant n'a jamais été inclus, donc il n'y a aucun besoin de faire appel à <code><a href="http://fr.php.net/require_once">require_once()</a></code>, un simple <code><a href="http://fr.php.net/require">require()</a></code> est suffisant.</li>
</ol>
<p>Certain pourrait me retorquer que l'appel à <code><a href="http://www.php.net/class_exists">class_exists()</a></code> a sa raison d'être si le développeur choisit d'utiliser directement <code><a href="http://www.php.net/manual/en/language.oop5.autoload.php">__autoload()</a></code> pour charger une classe à la demande, d'une manière analogue à <code><a href="http://fr.php.net/require_once">require_once()</a></code> ou <code><a href="http://fr.php.net/require">require()</a></code>.</p>
<p>Je leur répondrai que je ne vois pas alors l'intérêt d'utiliser le mécanisme d'<code><a href="http://www.php.net/manual/en/language.oop5.autoload.php">autoloading</a></code> si ce n'est pas pour s'en servir.</p>
<p>Ensuite, je vous ai induit en erreur, car il n'y a pas deux, mais bien trois paradoxes dans ce code.</p>
<p>Certain l'ont en parti détecté, mais sans aller jusqu'au bout de leur réflexion.</p>
<p>Ce troisième paradoxe est induit par l'utilisation du second paramètre passé à <code><a href="http://www.php.net/class_exists">class_exists()</a></code>, en l'occurence <code>false</code>.</p>
<p>Sans ce paramètre, <code><a href="http://www.php.net/class_exists">class_exists()</a></code>utilise le mécanisme d'<code><a href="http://www.php.net/manual/en/language.oop5.autoload.php">autoloading</a></code> pour tenter de charger la classe si elle n'existe pas.</p>
<p>Dans notre contexte, s'il n'avait pas été utilisé, il y aurait eu un réel risque de générer une boucle infinie dans le cas ou la classe que <code><a href="http://www.php.net/manual/en/language.oop5.autoload.php">__autoload()</a></code> doit charger n'existe pas, ce qui est forcément le cas puisque nous sommes justement dans ce cas lorsque cette fonction est appelée par <a href="http://www.php.net">PHP</a>.</p>
<p>En effet, <code><a href="http://www.php.net/manual/en/language.oop5.autoload.php=">__autoload()</a></code> aurait fait appel à <code><a href="http://www.php.net/class_exists">class_exists()</a></code> qui aurait fait appel à <code><a href="http://www.php.net/manual/en/language.oop5.autoload.php">__autoload()</a></code> qui aurait fait appel... vous connaissez la suite.</p>
<p>Le troisième paradoxe est donc qu'un ou plusieurs développeurs ont été suffisament intelligent pour utiliser correctement <code><a href="http://www.php.net/class_exists">class_exists()</a></code> dans le cadre d'une fonction <code><a href="http://www.php.net/manual/en/language.oop5.autoload.php">__autoload()</a></code> alors qu'ils faisaient dans le même temps quelque chose de complétement <del>con</del> inutile.</p>
<p>Enfin, certain ont relevé un problème relatif à l'utilisation de <code><a href="http://fr.php.net/dirname">dirname()</a></code>.</p>
<p>De mon point de vue, c'est plus un problème lié à la performance du code qu'un réel paradoxe.</p>
<p>Voici donc une version fonctionnellement identique du code concerné, mais corrigée et optimisée :</p>
<blockquote><pre><code>function __autoload($className)<br />{<br /> static $classesDirectory = null;<br /><br /> if ($classesDirectory === null)<br /> {<br /> $classesDirectory = realpath(dirname(__FILE__).'/../classes') . '/';<br /> }<br /><br /> require($classesDirectory.$className.'.php');<br />}</code></pre></blockquote>http://blog.mageekbox.net/?post/2009/10/14/Retour-sur-les-paradoxes#comment-formhttp://blog.mageekbox.net/?feed/atom/comments/74