Bug ou totallement con ?

zevy
Invité n'ayant pas de compte PHPfrance

27 juil. 2007, 14:26

Suite à un bug dans notre application, et après qq heures de recherche, nous avons extrait le bout de code suivant. Et là, quel étonnement. La fonction in_array() nous renvoi vrai alors que les valeurs testées sont bel et bien différentes... Démonstration :
<?php
$a = '00100100100100640514';
$b = '00100100100100640512';
$c = array();
array_push($c, $b);
echo "in_array sans param : ".in_array($a, $c)."<br />";   //renvoi vrai  :o
echo "in_array false : ".in_array($a, $c, false)."<br />";    //renvoi vrai  :o
echo "in_array true : ".in_array($a, $c, true)."<br />";      //renvoi faux
?>
Quelqu'un a une explication ?

Mammouth du PHP | 19672 Messages

27 juil. 2007, 14:37

Ça sent le bug dans le moteur PHP..., c'est en tous cas très surprenant et je n'ai pas trouvé d'explication cohérente... :-k
Codez en pensant que celui qui maintiendra votre code est un psychopathe qui connait votre adresse :axe:

vinz028
Invité n'ayant pas de compte PHPfrance

27 juil. 2007, 14:38

$a = '00100100100100640514';
$b = '00100100100100640512';


if ($a == $b)
  echo "vrai";
else
  echo "faux";
//retourne vrai !

if (strcmp($a, $b))
  echo "vrai";
else
  echo "faux";
//retourne vrai aussi !

Administrateur PHPfrance
Administrateur PHPfrance | 3088 Messages

27 juil. 2007, 14:38

C'est un exemple de retour de flamme du laxisme de PHP concernant les types de variables. Si tu ne précises pas que tu souhaites une comparaison "type safe" (donc avec les troisième paramètres sur true) beaucoup de fonctions (toutes?) PHP considèrent qu'une chaîne entièrement composée de chiffres doit être traitée comme un nombre. Et comme les nombres en question sont trop grands ils sont tous les deux tronqués à la plus grande valeur possible:
var_dump((int) $a, (int) $b);
D'ailleurs, je parle de fonctions mais c'est aussi valable pour les conditions if:
if ('00100100100100640514' == '00100100100100640512')
{
	echo "Surprise !";
}
Mon conseil : utilise des comparaisons strictes (=== ou le troisième paramètre de in_array()) à partout où c'est possible.