Incroyable bug de PHP

Ca fait maintenant 10 ans que je pratique le PHP ... et je viens seulement dernièrement de tomber une bug qui m'a coûté des heures de recherche car il me paraît complètement fou !

Du moins, pour le développeur que je suis, il m'interpelle car il va à l'encontre des principes de développement que je juge élémentaire...

Je vais faire bref : l'opérateur == de PHP est inadapté aux comparaisons de chaînes car son comportement est erroné dans le cas qui va suivre.

Dénichons le bug

Voici un exemple de code pour vous aider à comprendre :

<?php

test("1234", "1234");
test("1234", " 1234");
test("1234", "\n1234");
test("1234", "1234 ");
test("1234", "1234\n");

function test($v1, $v2) {
	echo "<h1>[".show_cr($v1)."] vs [".show_cr($v2)."]</h1>";
	echo my_var_dump($v1)."<br />";
	echo my_var_dump($v2)."<br />";
	if($v1 == $v2) {
		echo "EQUAL !";
	}
	else {
		echo "DIFFERENT !";
	}
}

function show_cr($var) {
	return str_replace("\n", "\\n", $var);
}

function my_var_dump($var) {
	ob_start();
	var_dump($var);
	$dump = show_cr(trim(ob_get_contents()));
	ob_end_clean();
	return $dump;
}

?>

Résultat d'éxécution :

[1234] vs [1234]
string(4) "1234"
string(4) "1234"
EQUAL !

[1234] vs [ 1234]
string(4) "1234"
string(5) " 1234"
EQUAL !

[1234] vs [\n1234]
string(4) "1234"
string(5) "\n1234"
EQUAL !

[1234] vs [1234 ]
string(4) "1234"
string(5) "1234 "
DIFFERENT !

[1234] vs [1234\n]
string(4) "1234"
string(5) "1234\n"
DIFFERENT !

Je suis sidéré ... qu'une comparaison entre deux variables de types différents engendre un cast automatique et mène à des incohérences, cela peut se comprendre.

Mais que la comparaison de deux String n'utilise pas une de String et face un pseudo cast ou ltrim bizarre (un appel de is_numeric en sous main ?), ca me dresse les cheveux sur la tête ...

En plus d'être incohérent, c'est pas performant ...

La solution consiste donc à remplacer toutes nos comparaisons de chaine par des strcmp ou strncmp ... vive la lisibilité du code :s

Et comme on peut pas redéfinir les opérateurs ... on peut même pas régler le problèmes nous-même ...

Je suis dégoûté, c'est n'importe quoi ...

Commentaires

Saleiri27/07/2010 16:17:24

C'est sur quelle version? Parce que, pour moi, ça donne aucune erreur.

arnapou27/07/2010 17:26:16

J'ai eu ce problème sur PHP v 5.3.2

Trigone30/08/2010 16:03:06

Oui, j'ai eu aussi un pb de cast automatique qui faussait des comparaisons.
De manière générale, quand on sait qu'on doit comparer des variables de type différent, il faut TOUJOURS faire un cast manuel.
Genre : if ((int)$chaine == $entier) ...
Ca évite les soucis.

Salieri29/04/2011 16:34:11

J'attends toujours des nouveaux articles :D

Lionel13/07/2011 12:57:59

Je vois que personne n'en parle mais il existe l'opérateur === qui lui fonctionne parfaitement avec ton exemple.
Je pensais que tous les dévs PHP l'utilisaient !

arnapou13/07/2011 19:47:31

Une chose est de comparer "1234" et 1234 avec (ou pas) opérateur ===
Là je parle de comparer deux chaines '1234" et "\n1234" avec ==, c'est complètement débile de tenter un cast automatique en int vu qu'on compare 2 strings ! Quel besoin peut avoir ce con d'interprêteur PHP de faire de l'auto cast vers int alors que les deux parties sont des strings !!!! C'est cela que je fustige !

Ajouter un commentaire

Envoyer

Cet article a été vu 3527 fois