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)

à suivre

Ou en attendant , .. la V.O. de John Herren.