?: Operator (der 'Elvis-Operator') in PHP

258

Ich habe das heute in einem PHP-Code gesehen:

$items = $items ?: $this->_handle->result('next', $this->_result, $this);

Ich kenne den hier verwendeten ?:Operator nicht. Es sieht aus wie ein ternärer Operator, aber der Ausdruck, anhand dessen bewertet werden soll, ob das Prädikat wahr ist, wurde weggelassen. Was heißt das?

alpha_juno
quelle

Antworten:

529

Der linke Operand wird ausgewertet , wenn der linke Operand wahr ist , und der rechte Operand ansonsten.

Im Pseudocode

foo = bar ?: baz;

grob aufgelöst zu

foo = bar ? bar : baz;

oder

if (bar) {
    foo = bar;
} else {
    foo = baz;
}

mit dem Unterschied, barder nur einmal ausgewertet wird.

Sie können dies auch verwenden, um einen "Selbsttest" durchzuführen, foowie in dem von Ihnen veröffentlichten Codebeispiel gezeigt:

foo = foo ?: bar;

Dies wird zugewiesen bar, foowenn foonull oder falsch ist, andernfalls bleibt es foounverändert.

Einige weitere Beispiele:

<?php
    var_dump(5 ?: 0); // 5
    var_dump(false ?: 0); // 0
    var_dump(null ?: 'foo'); // 'foo'
    var_dump(true ?: 123); // true
    var_dump('rock' ?: 'roll'); // 'rock'
?>

Übrigens heißt es Elvis-Operator .

Elvis-Betreiber

BalusC
quelle
11
Stellen Sie sicher, dass die Variable in der Klammer vorhanden ist, da sonst ein Fehler auftritt. PHP geht nicht nur davon aus, dass es einen Wert von nulloder irgendetwas hat. Sag einfach '
DanMan
20
Was lustig ist, ist, dass diese Antwort eine rekursive Schleife mit dem Wiki-Artikel bildet, der nicht vollständig erklärt, warum er als "Elvis-Operator" bezeichnet wird.
scheinbar amüsant
41
Ein bisschen weniger Operation, ein bisschen mehr Ausdruck bitte.
Aalaap
2
Warum nicht einfach ein ||. Also blah || 'default'?
Noitidart
10
@Noitidart Da der ||Operator im Gegensatz zu JS, wo der Operand ganz links zurückgegeben wird, in PHP immer einen Booleschen Wert zurückgibt.
Ksadowski
58

Siehe die Dokumente :

Seit PHP 5.3 ist es möglich, den mittleren Teil des ternären Operators wegzulassen. Der Ausdruck wird expr1 ?: expr3zurückgegeben, expr1wenn er expr1ausgewertet wird TRUE, expr3andernfalls.

Yacoby
quelle
10
Sie brauchen einen neuen Doc Writer, weil unweigerlich jemand fragen wird, was mit expr2 passiert ist. Ich habe es nur gedacht.
John K
7
Was zum Teufel? Ich finde das gerade heraus, gleich nach dem Upgrade auf PHP 7? Ich hätte das jahrelang benutzen können!
Buttle Butkus
TBH, die Dokumente sind korrekt. Was passiert expr2ist, ist, dass es einfach verschwunden ist und nicht ausgewertet wird. $this->expensiveComputation() ?: "nope"ist nicht identisch mit $this->expensiveComputation() ? $this->expensiveComputation() : "nope"- expr1 wird nur einmal ausgewertet.
Piskvor verließ das Gebäude
18

Seien Sie vorsichtig mit Arrays. Wir müssen danach eine Prüfvariable schreiben ?, weil:

  $params = ['param1' => 'value1',
             'param2' => 'value2',
             'param3' => 'value3',];

  $param1 = isset($params['param1'])?:null;
  $param2 = !empty($params['param2'])?:null;
  $param3 = $params['param3']?:null; // get E_NOTICE, if $params['param3'] eq false

  var_dump($param1,$param2,$param3);
  true // would like to expect `value1`
  true // would like to expect `value2`
  param3 // properly, but problem above

Aktualisiert

Von RFC. In Zukunft (in PHP 7) wird der Operator Null Coalesce Operator dies tun, zum Beispiel:

$param1 = $params['param1'] ?? null;
// Equivalent to:  $param1 = isset($params['param1']) ? $params['param1'] : null;
voodoo417
quelle
1
Dies beantwortet weder die Frage noch ist es für jemanden nützlich, der versucht zu verstehen, wann der Elvis-Operator verwendet werden soll.
Mark Amery
7
@ Mark Amery hmm .. Wirklich? Ist das nicht hilfreich? Haben Sie wirklich mit PHP gearbeitet und sich Tausende Fälle angesehen, in denen Sie mit ternär auf die Variablen des Arrays zugegriffen haben? Ok, ich habe den Text in "Sei vorsichtig mit Arrays ..."
geändert
also null coalesce und elvis sind gleich?
Nabeel Khan
7
@NabeelKhan Nein! Und das macht den Elvis-Operator in PHP imo irgendwie nutzlos. Der Elvis-Operator wertet einen Ausdruck aus und wenn er wahr ist, gibt er ihn zurück, andernfalls gibt er den letzten Teil zurück. Da PHP wenig typisiert ist, werden viele Dinge wahr oder falsch sein, und höchstwahrscheinlich werden die Dinge nicht das sein, was Sie wollen. Dh: Sie möchten einen Standardwert für eine Variable festlegen, wenn dieser nicht definiert ist. Wenn Sie den Elvis-Operator verwenden, sagt PHP, dass 0 nicht definiert ist, aber Sie möchten möglicherweise, dass 0 ... Deshalb erhält PHP 7 den Null Coalesce-Operator , Es wird Ihre Variable streng gegen Null testen, so dass PHP sagt, dass 0 nicht undefiniert ist.
Gregoire D.
1
@FuscaSoftware: Die Verwendung einer solchen Fehlerunterdrückung ist meiner Erfahrung nach keine gute Idee.
TeeHays
8

Eine weitere wichtige Überlegung: Der Elvis-Operator unterbricht den Zend Opcache-Tokenisierungsprozess. Ich fand das auf die harte Tour! Obwohl dies in späteren Versionen möglicherweise behoben wurde, kann ich bestätigen, dass dieses Problem in PHP 5.5.38 (mit integriertem Zend Opcache v7.0.6-dev) besteht.

Wenn Sie feststellen, dass einige Ihrer Dateien nicht in Zend Opcache zwischengespeichert werden können, kann dies einer der Gründe sein ... Ich hoffe, dies hilft!

Prasad Paradkar
quelle
4

Ja, das ist neu in PHP 5.3. Es gibt entweder den Wert des Testausdrucks zurück, wenn er als TRUE ausgewertet wird, oder den alternativen Wert, wenn er als FALSE ausgewertet wird.

Atli
quelle
2
Subtil falsch / irreführend; Keiner der Operanden muss ein Boolescher Wert sein. Was zählt ist, ob der erste Wert wahr ist , nicht ob er wahr ist TRUE.
Mark Amery
@ MarkAmery geklärt. Sollte ziemlich schwer sein, es auf diese Weise falsch zu interpretieren.
Atli