PHP et conversions implicites

Un exemple réel qui m'a fait perdre du temps : le danger du typage faible.

J'ai été contraint d'utiliser PHP. Je me suis dit que ce n'était pas grave, c'était juste un petit site à faire, qui ne prendrait pas beaucoup de temps. Après tout, PHP ne peut pas être si mauvais que ça ; des milliers de développeurs s'en servent tous les jours avec (plus ou moins de) succès. Bien sûr, par méfiance, la première ligne que j'ai écrite fut "error_reporting(E_ALL);".

À un endroit, j'ai souhaité concaténer deux chaines. Je sais pertinemment qu'il s'agit de l'opérateur "." en PHP, mais j'ai fait une erreur d'inattention : l'habitude d'autres langages m'a poussé à utiliser "+". Une erreur bête, ça peut arriver à tout le monde.

Regardez maintenant le code PHP suivant :

[php]
$a = "test1";
$b = "42e test";
echo ($a + $b);

La question est : qu'affiche-t-il à l'exécution ? Une erreur ? Non. Un avertissement ? Même pas. La concaténation des deux chaines ? Non plus, c'eût été trop intuitif. Ce code affiche "42". On pourrait faire le test et demander à 100 personnes : que devrait renvoyer l'expression "a1" + "4b" ? Je suis convaincu qu'aucune ne répondrait 4. En fonction de ses habitudes, on pourrait préférer soit une erreur, soit une concaténation. Je ne vois pas d'autre comportement intuitif possible.

En pratique, mon code était légèrement plus complexe que cela. Le résultat de la concaténation était ensuite passé dans une fonction de hachage. Je ne me suis donc pas rendu compte de l'erreur tout de suite. Ce n'est qu'après plusieurs jours que j'ai observé des conflits au niveau du hachage. Ce qui m'a fait maudire, une fois de plus, PHP et son système de typage.

Le problème, ici, c'est la conversion implicite. Une chaine de caractères ne devrait pas être convertie implicitement en entier. D'accord, la conversion de la chaine "4" vers l'entier 4 pourrait être débattue ; mais la conversion de la chaine "test" en 0 me semble vraiment dangereuse et malsaine.

Comments

1. On Wednesday, February 6 2008, 16:49 by Micha

int main ()
{
return atoi ("a1") + atoi ("4b");
}

C'est evident pour n'importe quel programmeur C :-) Le + travaille sur les nombres, et qu'est-ce qui convertit des chaines en nombres ? atoi, et atoi a le meme fonctionnement que la conversion implicite du PHP !

$ ./a.out && echo $?
4