PHP GOTCHAS!
À 07:02 dans la rubrique PHP / PEAR
←
/ #220
/ rss
/ →
Traduction de l'article http://devzone.zend.com/node/view/id/168
écrit par John Herren le Vendredi, Avril 21, 2006
Appelez-les obscures, appelez-les injustifiées, appelez-les des "erreurs de newbies."
Quelque soit le nom, vous les avez plus que probablement déclenchées vers le début dans votre apprentissage de codage en PHP par des comportements apparemment impairs ou illogiques du langage.
PHP étant un langage faiblement typé, des choses bizarres qui en découlent peuvent se produire. PHP est un langage facile à reprendre pour le codeur occasionnel
Aiguilles et bottes de foin
Disons que vous voulez repérer l'existence d'une chaîne à l'intérieur d'une autre chaîne -- trouvez l'aiguille dans la botte de foin. C'est une jolie tâche courrante. laissons l'utilisation la fonction de strpos() de l'assumer:
if (strpos('abcdefg','abc')) echo "yep j'ai trouvé!";
else echo "didn't find it..";
Attendez une seconde! Cette sous-chaîne est belle et bien dans cette chaîne. Pourquoi le retour de la fonction de strpos() est-il faux? jetons un coup d'oeil sur le manuel:
strpos -- Trouve la position d'un caractère dans une chaîne int strpos ( string haystack, mixed needle , int offset )
La fonction de strpos() renvoie un nombre entier indiquant la position (par conséquent le nom)! Puisque notre aiguille est trouvée au début de la chaîne, le retour est 0, qui est évalué à faux. En outre, le manuel dit:
Si needle n'est pas trouvé, la fonction retourne FALSE
Bon, tentons de patcher l'exemple comme ceci:
if (strpos('abcdefg','abc') != false) echo "yep j'ai trouvé!";
else echo "pas trouvé..";
Heik!? Notre valeur de retour 0 n'est pas égale à faux... ou bien si? Oui, le nombre entier 0 est évalué à faux. Nous devons aussi bien vérifier le type que la valeur :
if (strpos('abcdefg','abc') !== false) echo "yep j'ai trouvé!";
else echo "pas trouvé..";
En conclusion, nous obtenons le résultat désiré. L'opérateur de == compare la valeur tandis que === (et son inverse! = =) compare aussi bien le type que la valeur. Si vous passez en revue le bugtracker de PHP , vous verrez que ce piège en particulier a été soumis beaucoup, beaucoup de fois, et marqué comme faux de bogue à chaque fois.
Des Céphalopodes en mon code?
Voici un gotcha de amusant PHP que j'ai découvert avec certification de Zend PHP :
var_dump
(
0123
==
123
);
résultat
bool(false)
Ceci ne m'a semble n'avoir aucun sens. Alors j'ai découvert que mettre un zéro devant un nombre entier marque une notation octale, qui évalue au 123(base 8) en 83 décimal. Cette notation octale a été incluse dans PHP pour le rendre plus facile le travail avec les modes de fichier. Jetez un oeil dans le manuel de chmod() pour en savoir plus.
En bonus essayez les suivants
var_dump('0123' == '123'); // bool(true)
var_dump('0123' == 123); // bool(true)
var_dump('0123' === '123'); // bool(false)
var_dump(0123 === 123); // bool(false)
Constantes Consistante
Petit Jeu. Qu'imprimera le code suivant ?
//MY_UNDEFINED_CONSTANT really is undefined
var_dump
(
defined
(
'MY_UNDEFINED_CONSTANT'
));
if (
MY_UNDEFINED_CONSTANT
) echo
'Dave Gahan'
;
else
echo
'David Gilmour'
;
Si vous pensez que ca sera Gilmour, vous aurez tort
bool(false)
Dave Gahan
Si vous développez en E_NOTICE, vous verrez le message de PHP
Notice: Use of undefined constant MY_UNDEFINED_CONSTANT - assumed 'MY_UNDEFINED_CONSTANT'
Mais pas si vous masquez ces erreurs.
Dans tous les cas, vous devriez vous rappeler que des constantes non définies sont traitées comme des chaînes dont le contenu est le nom de la constante. Et la chaîne "MY_UNDEFINED_CONSTANT" est évaluée quand elle est castée comme booléen.
Mon professeur de math mentait ?
var_dump(0.7 + 0.1 == 0.8); //outputs bool(false)
crack boum hiiiiiiiiiiiii
Et oui, les nombres à virgule flottante ne valent visiblement pas ce qu'ils semblent.
La précision devient un facteur avec des nombres de virgule flottante.
PHP ne semble pas faire la chose logiquement quand on compare deux float,
et ceci est dû à la représentation interne des nombres.
La solution est qu'il ne faut simplement jamais comparer l'égalité des nombres flottants!
Mon prof de "d'intro aux systèmes logiques" était aussi un menteur ?!
$x = true AND false
;
var_dump
(
$x
);
//affiche bool(true)
Pourquoi l'action 'AND' réagit est-elle comme l'opérateur 'OR'?
Joker?
Peut-être ceci aidera:
$y
= (
$x
=
true
and
false
);
var_dump
(
$x
);
//affiche bool(true)
var_dump
(
$y
);
//affiche bool(false)








Commentaires
1. Le jeudi 27 avril 2006 à 11:15, par Moosh
Ajouter un commentaire
Les commentaires pour ce billet sont fermés.