Un piège en PHP
- 08/04/2008
PHP://
Un piège en PHPAprès plus de 7 ans d'utilisation de PHP je suis tombé sur un piège qui me surprend (tout autant que je ne comprend pas comment je n'ai pas rencontré cela plus tôt - j'ai plutôt dû ne pas y faire attention je suppose...).
Bref, l'autre jour, travaillant sur un code que je n'ai pas écrit, je ne comprenais pas pourquoi ce que j'étais en train de rajouter ne marchait pas. En fait, tout se passait comme si une variable tableau donnant l'identification de l'utilisateur courant était vide, mais comme aucune erreur PHP ne venait me signaler un problème, je cherchais ailleurs...
En fait la variable valait bien NULL, et était utilisée sous cette forme : $var['auth']. Et PHP ne disait rien, pour une raison qui m'échappe.
Voici un exemple de code qui montre le problème
<?php
$var = NULL;
echo "valeur " . $var['user_id'] . '<br>';
?>
Pour moi la tentative d'accéder à un indice n'existant pas dans un tableau (ou dans le pseudo-tableau que forme une chaine de caractères) devrait faire hurler les mécanismes de sécurité du langage, et signaler une erreur d'exécution.
Notez que ce code ci affiche bien une erreur sur l'inexistence de l'indice 'auth', que le transtypage se fasse en chaine ou en tableau :
<?php
$var = NULL;
$var = (array) $var;
echo "valeur " . $var['user_id'] . '<br>';
?>
Je ne vois vraiment pas pourquoi PHP accepte l'opérateur [] sur un entier sans rien dire...
Alors bon, certes au départ le soucis vient d'une variable extérieur à ma fonction, dont la déclaration se trouve loin de l'utilisation, et donc d'un problème de contrôle global sur le code. Ceci étant, l'interpréteur m'aurait prévenu, j'aurai perdu moins de temps...
La solution a été la suivante : un assert() chargé de s'assurer de la nature de ce qui rentre dans ma fonction.
<?php
assert(is_array($var));
?>
Notez que le soucis existe autant avec PHP 5.2.5 qu'avec PHP 4.7.
Rubriques des billets
- Agilité - 16 billets
- Archerie - 8 billets
- Avis - 48 billets
- Cultures - 9 billets
- Délires - 34 billets
- Démocrachie - 5 billets
- Développement - 22 billets
- Développement web - 18 billets
- Ergonomie - 17 billets
- Geekerie - 10 billets
- Inclassable - 4 billets
- Informatique - 19 billets
- Littératures - 34 billets
- PHP - 5 billets
- Poor Lonesome Coder - 19 billets
- Régalons-nous - 6 billets
- Sortons! - 2 billets
- Travail - 16 billets
- Voyages - 2 billets
- Webmasteriat - 18 billets
Commentaires(s)
- 2008-04-08 13:39:53 - Hugo
Tu as pensé à afficher TOUTES les erreurs en environnement de développement ? Cela se configure bien entendu dans le php.ini et t'aurais sans doute permis d'éviter ce genre de désagrément.
- 2008-04-08 13:52:17 - Cédric
Oui, je ne l'ai pas mentionné mais un poste de développement qui ne serait pas en display_errors=On et error_reporting(E_ALL|E_STRICT) me semblerait trop risqué.
Dans tous les autres cas les erreurs s'affichent bien, mais si tu arrive à faire afficher une erreur avec le premier bout de code, je veux bien ton php.ini. - 2008-04-08 14:24:03 - Gérald
J'ai voulu vérifier sur mon poste (j'avoue que je me refusait à croire qu'aucune notice était générée)..... et effectivement, c'est le cas, PHP ne dit absolument rien !
Dingue.... - 2008-04-08 16:00:42 - Nico
bizarre, en effet. ..
sinon j'utilise toujours unset($var) à la place de $var = null; - 2008-04-08 16:32:49 - Cédric
Sauf que $var = null n'a rien à voir avec unset(). D'un côté je met une valeur, de l'autre je détruis la variable. En l'occurrence cette valeur est celle qu'avait réellement la variable incriminée dans mon cas, mais j'aurai pu mettre une valeur numérique à la place.
- 2008-04-08 17:05:45 - Nico
vu sur http://fr.php.net/types.string : "NULL est toujours converti en une chaîne de caractères vide."
or l'expression suivante génère bien le warning attendu :
$var = ''; echo $var['user_id']; echo $var[0];
sans doute la conversion de NULL en chaîne de caractère doit merdouiller quelque part ? - 2008-04-08 17:33:43 - Cédric
Certes, mais en plus si on met 1 à la place de NULL le résultat est le même : absence totale d'erreur.
- 2008-04-08 17:50:25 - Nico
certes, d'où ma conclusion sur le merdouillage ;)
Ecrire votre commentaire
08/04/2008 - Systeme