332 votes

AND et && comme opérateur

J'ai une base de code où les développeurs ont décidé d'utiliser AND y OR au lieu de && y || .

Je sais qu'il existe une différence dans la préséance des opérateurs ( && va avant and ), mais avec le cadre donné ( PrestaShop pour être précis), ce n'est clairement pas une raison.

Quelle version utilisez-vous ? Est-ce que and plus facile à lire que && ? Ou bien n'y a-t-il aucune différence ?

1 votes

Notez que ~ est l'opérateur bit-wise NOT et non le logique ;-)

2 votes

Oui, je sais. Mauvaises habitudes :) . C'est un peu étrange qu'en PHP, il y ait des 'and', 'or' et 'xor', mais pas de 'not', n'est-ce pas ?

1 votes

@ts : la réponse correcte ici est celle fournie par R. Bemrose stackoverflow.com/questions/2803321/et-vs-as-operator/

715voto

Powerlord Points 43989

Si vous utilisez AND y OR vous finirez par vous faire piéger par quelque chose comme ça :

$this_one = true;
$that = false;

$truthiness = $this_one and $that;

Vous voulez deviner ce que $truthiness égaux ?

Si vous avez dit false ... bzzzt, désolé, faux !

$truthiness ci-dessus a la valeur true . Pourquoi ? = a un plus haute priorité que and . L'ajout de parenthèses pour montrer l'ordre implicite rend cela plus clair :

($truthiness = $this_one) and $that

Si vous avez utilisé && au lieu de and dans le premier exemple de code, il fonctionnerait comme prévu et serait false .

Comme discuté dans les commentaires ci-dessous, cela fonctionne également pour obtenir la valeur correcte, car les parenthèses ont une plus grande priorité que = :

$truthiness = ($this_one and $that)

154 votes

+1 : cela devrait être clairement indiqué dans la documentation de PHP, ou PHP devrait changer et donner la même priorité à ces opérateurs ou DEPRECATE. and or une fois pour toutes. J'ai vu trop de gens qui pensaient qu'il s'agissait exactement de la même chose et les réponses ici sont plus des témoignages.

12 votes

En fait, d'autres langages (par exemple, Perl et Ruby) ont également ces variantes avec la même distinction de précédence, il ne serait donc pas judicieux de s'écarter de ce standard (même si cela peut être déroutant pour les débutants) en rendant la précédence égale en PHP. Sans parler de la compatibilité ascendante de nombreuses applications PHP.

25 votes

L'incapacité des gens à lire la documentation d'un langage ne rend pas les décisions de ce dernier mauvaises. Comme le note Mladen, Perl et Ruby utilisent également ces opérateurs supplémentaires, et avec les mêmes précédences. Cela permet des constructions telles que $foo and bar() qui sont de bons raccourcis pour les instructions if. Si un comportement inattendu (dû à une mauvaise documentation ou au fait de ne pas la lire) était une raison de ne pas utiliser quelque chose, nous ne parlerions pas du tout de l'utilisation de PHP.

47voto

adamJLev Points 5892

Selon l'utilisation qui en est faite, cela peut être nécessaire et même pratique. http://php.net/manual/en/language.operators.logical.php

// "||" has a greater precedence than "or"

// The result of the expression (false || true) is assigned to $e
// Acts like: ($e = (false || true))
$e = false || true;

// The constant false is assigned to $f and then true is ignored
// Acts like: (($f = false) or true)
$f = false or true;

Mais dans la plupart des cas, il semble qu'il s'agisse plutôt d'une question de goût des développeurs, comme chaque occurrence de ce problème que j'ai vu dans le cadre de CodeIgniter, comme @Sarfraz l'a mentionné.

2 votes

Il convient de noter que le "true" n'est pas ignoré si l'expression fait partie d'une déclaration plus large. Considérons le cas suivant if ($f = false or true) $f = true; - le résultat serait que $f devient vrai à la fin, car l'expression est évaluée comme vraie dans l'ensemble.

1 votes

Non, vous avez simplement écrasé la variable plus tard. l'expression est toujours évaluée à false, puis vous l'avez écrasée avec true dans la ligne suivante.

2 votes

En fait, il avait raison. D'abord, $f est affecté à faux - mais la condition est évaluée à vrai, donc alors $f est écrasé. Si la condition est évaluée à faux, $f n'aurait jamais été écrasé de toute façon.

13voto

Juann Strauss Points 1677

Par sécurité, je mets toujours mes comparaisons entre parenthèses et je les espace. Ainsi, je n'ai pas à me fier à la préséance des opérateurs :

if( 
    ((i==0) && (b==2)) 
    || 
    ((c==3) && !(f==5)) 
  )

32 votes

Personnellement, je pense que le fait d'ajouter des parenthèses inutiles rend la lecture plus confuse que si l'on avait juste ce dont on a besoin. Par exemple, je pense que ceci est beaucoup plus facile à lire : if (($i == 0 && $b == 2) || ($c == 3 && $f != 5))

4 votes

Je pense que c'est le plus beau morceau de code que j'ai regardé de toute la journée. Bon travail.

0 votes

Comme PHP est un langage interprété, il fonctionnera rapidement si vous n'utilisez pas d'espaces inutiles ou de nouvelles lignes dans votre code. Si vous faites la même chose dans un langage compilé, cela prendra plus de temps à la compilation mais cela n'aura pas d'effet à l'exécution. Je ne veux pas dire que faire cela une fois marquera une différence mais sur une application entière utilisant php + javascript tous les deux écrits comme l'exemple... les temps de chargement seront plus grands pour sûr. Explication : Les espaces blancs et les nouvelles lignes sont ignorés, mais pour les ignorer, ils doivent être vérifiés. Cela se produit au moment de l'exécution sur les langages interprétés et lors de la compilation sur les langages compilés.

12voto

arviman Points 1663

La préséance diffère entre && y y (&& a une précédence plus élevée que and), ce qui prête à confusion lorsqu'il est combiné avec un opérateur ternaire. Par exemple,

$predA && $predB ? "foo" : "bar"

retournera un chaîne de caractères alors que

$predA and $predB ? "foo" : "bar"

retournera un boolean .

0voto

nuqqsa Points 3373

Je suppose que c'est une question de goût, même si le fait de les mélanger (par erreur) peut entraîner certains comportements indésirables :

true && false || false; // returns false

true and false || false; // returns true

Par conséquent, l'utilisation de && et || est plus sûre car ils ont la plus haute priorité. En ce qui concerne la lisibilité, je dirais que ces opérateurs sont suffisamment universels.

UPDATE : A propos des commentaires disant que les deux opérations retournent false ... eh bien, en fait le code ci-dessus ne retourne rien, je suis désolé pour l'ambiguïté. Pour clarifier : le comportement dans le deuxième cas dépend de la façon dont le résultat de l'opération est utilisé. Observez comment la précédence des opérateurs entre en jeu ici :

var_dump(true and false || false); // bool(false)

$a = true and false || false; var_dump($a); // bool(true)

La raison pour laquelle $a === true c'est parce que l'opérateur d'affectation a la priorité sur tout opérateur logique, comme déjà très bien expliqué dans d'autres réponses.

16 votes

Ce n'est pas vrai, ils retournent tous false.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X