web-dev-qa-db-fra.com

if ('constant' == $ variable) vs. if ($ variable == 'constant')

Dernièrement, j'ai beaucoup travaillé en PHP et en particulier dans le cadre WordPress. Je remarque beaucoup de code sous la forme de:

if ( 1 == $options['postlink'] )

Où je m'attendais à voir:

if ( $options['postlink'] == 1 )

Est-ce une convention trouvée dans certains langages/cadres? Y a-t-il une raison pour laquelle la première approche est préférable à la seconde (du point de vue du traitement, ou du point de vue de l'analyse ou même du point de vue humain?)

Ou est-ce simplement une question de goût? J'ai toujours pensé qu'il était préférable, lors d'un test, que l'élément variable testé par rapport à une constante soit à gauche. Il semble mieux correspondre à la façon dont nous poserions la question en langage naturel: "si le gâteau est au chocolat" plutôt que "si le chocolat est le gâteau".

50
Tom Auger

La principale raison de cette opération (dite "conditionnelle Yoda") est de prévenir les accidents par lesquels vous utilisez accidentellement un opérateur d'affectation (=) au lieu de l'opérateur de comparaison égal (==).

Autrement dit, si vous avez fait l'erreur de faire:

$foo = 5;
if ($foo = 1) {
  // Stuff
}

L'instruction sera évaluée à true (ou, dans le cas de certains langages - comme PHP - une valeur véridique) et vous aurez un bug difficile à trouver.

Mais si vous l'avez fait:

$foo = 5;
if (1 = $foo) {
  // Stuff
}

Vous recevrez une erreur fatale car vous ne pouvez pas attribuer $foo à un entier.

Mais comme vous l'avez souligné, inverser l'ordre rend généralement les choses moins lisibles. Ainsi, de nombreuses normes de codage (mais pas toutes, y compris WordPress ) suggèrent ou nécessitent $foo == 1 malgré les avantages de la chasse aux bogues de 1 == $foo.

Généralement, mon conseil est de suivre la norme de codage établie, s'il y en a une: pour WordPress, cela signifie utiliser les conditions Yoda.

Lorsqu'il n'y en a pas, et qu'il est impossible d'en établir un par consensus avec vos pairs, c'est le choix du concessionnaire.

84
user8

Il s'agit d'un mécanisme de codage défensif destiné à empêcher une utilisation accidentelle de l'opérateur d'affectation.

Considérez une mauvaise utilisation/erreur de l'opérateur d'affectation à la place de l'opérateur d'égalité

if ( $options['postlink'] = 1  )

Le conditionnel ci-dessus retournerait toujours vrai, mais ce n'est probablement pas ce que le programmeur d'origine avait en tête. Considérez, à sa place, ce

if( 1 = $options['postlink'])

Ici, PHP (et la plupart des autres langages) refuseraient de s'exécuter, car il est impossible d'affecter n'importe quoi à la valeur fixe de 1. En codant toutes les instructions conditionnelles de cette manière, vous vous assurez automatiquement qu'aucune utilisation accidentelle d'un opérateur d'affectation dans un conditionnel.

13
Alan Storm

J'aime utiliser cette convention dans Java pour supprimer la possibilité d'une exception de pointeur nul. Donc, quelque chose comme ça ne vous causera aucun problème ni n'aura besoin de code supplémentaire:

String foo = null;

if ("bar".equals(foo))
{
    //Do something
}
9
Ben Newman

En pratique, de nombreux compilateurs vous donneront un avertissement si vous écrivez "if (x = 1)" au lieu de "if (x == 1)" car il s'agit très probablement d'une erreur.

Avec Clang, vous pouvez éviter l'avertissement en disant effectivement au compilateur "Je le pense et je sais ce que je fais", et cela se fait en écrivant "if ((x = 1))". Notez les parenthèses supplémentaires. Cela fonctionne également dans d'autres situations. instruction if (false); peut vous avertir que l'instruction n'est jamais exécutée; instruction if ((false)); ne donne pas cet avertissement.

0
gnasher729