Verwendung des ternären Operators von PHP mit nur zwei Argumenten


9

Ich habe kürzlich einen Teil meines Codes überprüft und festgestellt, dass ich in einem Anfall von Geistesabwesenheit eine Struktur wie die folgende hinterlassen habe:

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

Nun, dies hat nicht das getan, was es soll und ist falsch , aber da diese Eigenschaft jetzt immer festgelegt ist, hat es einwandfrei funktioniert und es gibt seit 5.3 keinen Syntaxfehler aufgrund der folgenden Änderung :

Seit PHP 5.3 ist es möglich, den mittleren Teil des ternären Operators wegzulassen. Ausdruck expr1 ?: Expr3 gibt expr1 zurück, wenn expr1 TRUE ergibt, andernfalls expr3.

Ich war mir dieser Änderung nicht bewusst und bin jetzt gespannt, ob ich sie verwenden sollte oder nicht. Dies ist etwas, was mir in Sprachen wie Ruby schmerzlich gefehlt hat, wo man zB a = b || centweder einen boder ceinen "echten" Booleschen Wert erhalten kann. Die Syntax, die sie für den ternären Operator gewählt haben, scheint mir jedoch ein wenig kontraintuitiv zu sein. Sollte ich dies im Produktionscode verwenden? Es warf mich definitiv, als ich es zufällig sah.


Sie sollten den Null-Koaleszenz-Operator für diesen Varsolp verwenden. Techflirt.com/null-coalescing-operator-php
Ankur Kumar Singh

Antworten:


7

Der ternäre bedingte Operator ohne das zweite Argument ist etwas neu, ähnelt jedoch 1 dem Null-Koaleszenz- Operator, der in anderen von Algol abgeleiteten Sprachen wie C # und Perl und, wie Sie bereits erwähnt haben, dem ||Operator in Ruby (und JavaScript) zu finden ist.

Es sieht auf den ersten Blick seltsam aus, ist aber nicht zu weit draußen (zumal es Präzedenzfälle für ähnliche Operatoren in anderen Sprachen gibt) und kann eine Menge Tastenanschläge sparen. Und wenn das, was mit dem Namespace delimiter ( \) passiert ist, ein Hinweis ist, werden seltsame Syntaxen schließlich von der PHP-Community übernommen.

Eines der Hauptprobleme, mit denen PHP-Anwendungen konfrontiert sind, ist die (manchmal) unerträglich lange Verzögerungszeit zwischen der Veröffentlichung einer neuen Version von PHP und dem Beginn der Unterstützung durch Hosts. Dies führt zu Problemen, bei denen Sie mit älteren PHP-Versionen abwärtskompatibel sein müssen, ohne auf solche praktischen Änderungen verzichten zu müssen.

Wenn Ihnen das nichts ausmacht und Ihr Team der Verwendung zustimmt (oder wenn Sie ein Einzelentwickler sind, wenn Sie damit vertraut sind), entscheiden Sie sich auf jeden Fall dafür. Wie beim Namespace-Trennzeichen denke ich wirklich, dass es wirklich darum geht, wann und nicht ob es in allen zukünftigen PHP-Projekten akzeptabel sein wird.


Hinweis 1 : Aber nicht identisch, da Null-Koaleszenz-Operatoren nur Nicht-Null-Werte (und keine Wahrheitswerte wie PHP) testen und die ?:Syntax undefinierte Hinweise nicht unterdrückt, wie Sie in den Kommentaren erwähnt haben .


Im Moment besteht mein "Team" nur aus mir. Das Hosting ist kein Problem, da wir im Allgemeinen 98% der von uns erstellten Websites hosten und zusätzlich zu 5.3.6 hosten. Mir ist klar, dass die Funktionalität selbst nicht so ungewöhnlich ist, nur die Syntax dafür, die die Wurzel meiner Frage war. Es gibt auch das Problem, dass es sich nicht wie ein Null-Koaleszenz-Operator ohne mehr Syntax verhält ( @um Hinweise auf undefinierte Dinge zu verbergen).
Matthew Scharley

3
@MatthewScharley Wenn das Debakel um das Namespace-Trennzeichen (\) ein Hinweis ist, ist die seltsame Syntax kein Hindernis für eine breite Akzeptanz in PHP. Es kommt wirklich darauf an, wann und nicht ob Sie damit beginnen sollten.

3

Für mich sieht das nach einem Fehler im Code aus. Es sieht falsch aus, und im Allgemeinen vermeide ich die Verwendung einer Syntax, die so aussieht, als hätten Sie einen Fehler gemacht, um ein paar Tastenanschläge zu speichern. Wenn Sie (oder jemand anderes) später zurückkehren, um den Code zu lesen, wird diese Zeile Sie wahrscheinlich stolpern lassen und Sie müssen Zeit damit verbringen, zu analysieren, was sie tut, was im Wesentlichen eine einfache Operation ist.


Das angegebene Beispiel ist falsch . Eine korrekte Verwendung der Funktionalität wie beabsichtigt wäre $foo = @$bar ?: 'baz'gleichbedeutend mit $foo = (@$bar ? $bar : 'baz'). Ich stimme Ihren Kommentaren jedoch zu.
Matthew Scharley

1

Nun, PHP hat einen booleschen Typ und der ||Operator gibt einen Booleschen Wert zurück. In PHP ist das Ergebnis $a || $bein Boolescher Wert. Dies stimmt überein, &&da &&es wenig Sinn macht, den einen oder anderen zurückzugeben, aber Sinn macht, true/ zurückzugeben false. Es klingt auch ziemlich logisch, wenn alle booleschen Operatoren bools zurückgeben.

Außerdem ist dies keine Erfindung von PHP, sondern folgt C, wo viele Designelemente von "klassischem" PHP herkommen. Zitat aus §6.5.14 des C99-Standards:

Die || Der Operator muss 1 ergeben, wenn einer seiner Operanden ungleich 0 ist. Andernfalls ergibt sich 0. Das Ergebnis hat den Typ int.

Und nun, ob Sie es verwenden sollten ?: Oder nicht, kann nicht in der allgemeinen Form beantwortet werden, aber denken Sie daran: Der beste Weg zur Sprache besteht darin, die darin enthaltenen Konstrukte zu verwenden und die darin vorgeschlagenen Paradigmen zu verwenden. Es macht wenig Sinn, Java-Code wie C-Code zu schreiben oder umgekehrt ;-)


0

Ich denke, es ist ein sehr nützlicher Operator und sollte auf jeden Fall verwendet werden, da der Sprachstandard ihn explizit definiert.

Beachten Sie, dass es offiziell den Elvis-Operator in Grooy heißt (warum? Schauen Sie es sich genau an!) Und vorgeschlagen wurde, in Java 7 eingeführt zu werden.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.