jeudi 29 octobre 2009
Sujet ridicule vous direz, mais pas si bête que ça quand on y pense. Dans le cadre d'une simulation de cours de programmation 101, je vous pose la question : comment effectuez vous la comparaison d'une variable avec une constante ?
Prenez 2 secondes pour y réfléchir et poursuivez votre lecture. Dans tous les langages de programmation, il existe un opérateur d'assignation et un opérateur de comparaison. Dans le cas de PHP, le premier est le symbole = alors que le second est un ==.
D'abord la réponse : la façon la plus sûre de comparer une valeur serait de placer la constante en premier :
if(CONSTANTE == $variable){La raison : parce que si vous faites la gaffe de faire le contraire et par mégarde vous utilisez l'opérateur d'assignation, PHP ne lancera pas d'erreur et le code s'exécutera sans livrer les résultats attendus et vous devrez en chercher la raison (à moins que votre éditeur soit assez intelligent pour vous les faire remarquer - comme NetBeans).
// ...
}
if($variable = CONSTANTE){En inversant l'ordre de comparaison, on s'assure que PHP lance un avertissement si on utilise l'assignation plutôt que le == :
// ...
}
if(CONSTANTE = $variable){Parse error: syntax error, unexpected '=' in file...
// oups, on ne peut pas assigner de valeur à une constante
}
Je soulève le point car j'ai moi-même fait l'erreur récemment malgré plusieurs années d'expérience. Peut-être est-ce le temps de faire des ajustements et de réviser nos habitudes de codage ?
C'est la notation Yoda, je l'utilise mais elle a deux défauts
1° elle s'exprime comme yoda, ce la rend peu lisible
2° si on est plusieurs développeurs ils ce peut que certains n'arriveront pas a prendre le réflexe de cette notation et donc on est moins protégé qu'il n'y parait.
Il vaut donc mieux s’attaquer à la source du problème : jamais d'assignation dans une condition
Pour ce faire il faut faire passer le code dans un validateur.
CodeSniffer par exemple, ou le checkcode de Zend_studio...
attention
fini les while ( $row = fetchFromFoo())
il faut écrire while ( false !== $row = fetchFromFoo())