Utiliser l'opérateur ternaire de PHP avec seulement deux arguments

9

Je revoyais récemment une partie de mon code et j'ai remarqué que dans un accès de distraction, j'avais laissé une structure comme la suivante:

$guid = empty($subscription->guid) ?  : $subscription->guid;

Maintenant, cela ne faisait pas ce qu'il était censé faire et c'est faux , mais puisque cette propriété est toujours définie maintenant, cela fonctionnait bien, et il n'y a pas d'erreur de syntaxe depuis 5.3 à cause du changement suivant :

Depuis PHP 5.3, il est possible de laisser de côté la partie centrale de l'opérateur ternaire. Expression expr1?: Expr3 renvoie expr1 si expr1 a la valeur TRUE, et expr3 sinon.

Je n'étais pas au courant de ce changement, et maintenant je suis curieux de savoir si je devrais l'utiliser ou non. C'est quelque chose qui me manquait cruellement dans des langages comme le rubis où vous pouvez par exemple, a = b || cobtenir soit bou cplutôt un "vrai" booléen. Cependant, la syntaxe qu'ils ont choisie pour l'opérateur ternaire me semble un peu contre-intuitive. Dois-je utiliser cela dans le code de production? Il m'a définitivement jeté quand je l'ai vu par accident.

Matthew Scharley
la source
Vous devez utiliser l'opérateur de coalescence nulle pour cela Varsolp techflirt.com/null-coalescing-operator-php
Ankur Kumar Singh

Réponses:

7

L'opérateur conditionnel ternaire sans le deuxième argument est un peu nouveau, mais il est similaire 1 à l' opérateur de coalescence nulle trouvé dans d'autres langages dérivés d'Algol comme C # et Perl, et comme vous le mentionnez, l' ||opérateur en Ruby (et JavaScript).

Cela a l'air bizarre au début, mais ce n'est pas trop là-bas (d'autant plus qu'il existe des précédents pour des opérateurs similaires dans d'autres langues), et peut économiser beaucoup de frappes. Et, si ce qui s'est passé avec le délimiteur d'espace de noms ( \) est une indication, des syntaxes étranges seront finalement adoptées par la communauté PHP.

Mais l'un des problèmes majeurs auxquels les applications PHP ont tendance à être confronté est le délai (parfois) atrocement long entre la publication d'une nouvelle version de PHP et le moment où les hôtes commencent à la prendre en charge. Cela conduit à des problèmes où vous devez être rétrocompatible avec les anciennes versions de PHP, en renonçant à utiliser des changements de commodité comme celui-ci.

Si cela ne vous préoccupe pas et que votre équipe est d'accord sur son utilisation (ou si vous êtes un développeur solo, si vous êtes à l'aise avec cela), allez-y certainement. Comme le délimiteur d'espace de noms, je pense vraiment que ce sera vraiment une question de moment, pas si, il sera acceptable dans tous les futurs projets PHP.


Remarque 1 : mais pas identique, étant donné que les opérateurs de coalescence nulle ne testent que les valeurs non nulles (et non les valeurs véridiques comme PHP), et la ?:syntaxe ne supprime pas les avis non définis comme vous l'avez mentionné dans les commentaires .

Communauté
la source
Pour le moment, mon «équipe» se compose uniquement de moi. L'hébergement n'est pas un problème car nous hébergeons généralement 98% des sites que nous construisons, et nous hébergeons en plus de 5.3.6. Je me rends compte que la fonctionnalité elle-même n'est pas si inhabituelle, juste sa syntaxe qui était à l'origine de ma question. Il y a aussi le problème où il n'agit pas comme un opérateur de coalescence nulle sans plus de syntaxe ( @pour masquer les avis sur des choses non définies).
Matthew Scharley
3
@MatthewScharley Si la débâcle du délimiteur d'espace de noms (\) est une indication, une syntaxe étrange n'est pas un obstacle à une adoption généralisée en PHP. Cela revient vraiment à savoir quand, et non si, vous devriez commencer à l'utiliser.
3

Pour moi, cela ressemble à une erreur dans le code. Cela semble faux, et en général, j'évite d'utiliser une syntaxe qui semble avoir fait une erreur pour sauver quelques frappes. Lorsque vous (ou quelqu'un d'autre) revenez lire le code plus tard, je pense que cette ligne va vous déclencher et vous obliger à passer du temps à analyser ce qu'il fait, pour ce qui est essentiellement une opération simple.

MattBelanger
la source
L'exemple donné est faux . Une utilisation correcte de la fonctionnalité comme prévu serait $foo = @$bar ?: 'baz'équivalente à $foo = (@$bar ? $bar : 'baz'). Je suis cependant d'accord avec vos commentaires.
Matthew Scharley
1

Eh bien, PHP a un type booléen et l' ||opérateur renvoie un booléen, donc en PHP le résultat de $a || $best un booléen, cela est cohérent avec &&car &&cela n'a pas de sens de renvoyer l'un ou l'autre mais a du sens de retourner true/ false. Le fait que tous les opérateurs booléens renvoient des bools semble tout aussi logique.

De plus, il ne s'agit pas d'une invention de PHP, mais du C, d'où proviennent de nombreux éléments de conception de PHP "classique". Citant du §6.5.14 de la norme C99:

Le || L'opérateur doit donner 1 si l'un de ses opérandes est différent de 0; sinon, il donne 0. Le résultat a le type int.

Et, eh bien, si vous devez utiliser?: Ou non ne peut pas être répondu sous la forme générale, mais l'esprit: La meilleure façon de parler est d'utiliser les constructions qu'il fournit et d'utiliser les paradigmes qu'il suggère. Il n'y a pas de sens à écrire du code Java comme du code C, ou l'inverse ;-)

johannes
la source
0

Je pense que c'est un opérateur très utile et devrait certainement être utilisé puisque la norme de langage le définit explicitement.

Notez qu'il s'appelle officiellement l' opérateur Elvis dans Grooy (pourquoi? Regardez-le de près!), Et qu'il avait été proposé d'être introduit dans Java 7.

Michael Borgwardt
la source