?: operator („operator Elvisa”) w PHP

257

Widziałem to dzisiaj w jakimś kodzie PHP:

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

Nie znam ?:operatora używanego tutaj. Wygląda jak operator trójskładnikowy, ale pominięto wyrażenie służące do oceny, czy predykat jest prawdziwy. Co to znaczy?

alpha_juno
źródło

Odpowiedzi:

528

Ocenia lewy operand, czy lewy operand jest prawdziwy , a prawy w przeciwnym razie.

W pseudokodzie

foo = bar ?: baz;

z grubsza rozwiązuje

foo = bar ? bar : baz;

lub

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

z różnicą, która barzostanie oceniona tylko raz.

Możesz także użyć tego do „samokontroli”, foojak pokazano w opublikowanym przykładzie kodu:

foo = foo ?: bar;

Spowoduje to przypisanie bardo fooif foojest zerowy lub falsey, w przeciwnym razie pozostanie fooniezmieniony.

Kilka innych przykładów:

<?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'
?>

Nawiasem mówiąc, nazywa się to operatorem Elvisa .

Operator Elvisa

BalusC
źródło
11
Upewnij się jednak, że zmienna w nawiasach istnieje, albo będziesz zgłaszać błąd. PHP nie tylko przyjmie, że ma wartość nulllub coś. Tylko
mówię
20
Zabawne jest to, że ta odpowiedź tworzy rekurencyjną pętlę z artykułem Wiki, który nie wyjaśnił w pełni, dlaczego nazywa się „operatorem Elvisa”.
wydaje się. Zabawne
41
Trochę mniej operacji, proszę trochę więcej wyrazu.
aalaap
2
Dlaczego nie skorzystać z ||. Tak blah || 'default'?
Noitidart
10
@Noitidart Ponieważ, inaczej niż w JS, gdzie zwraca najbardziej lewy operand prawdziwy, w PHP ||operator zawsze zwraca wartość logiczną.
ksadowski
58

Zobacz dokumenty :

Od wersji PHP 5.3 można pominąć środkową część operatora trójskładnikowego. Wyrażenie expr1 ?: expr3zwraca, expr1jeśli expr1ewaluuje TRUEi expr3inaczej.

Yacoby
źródło
10
Potrzebują nowego pisarza doc, ponieważ nieuchronnie ktoś zapyta, co się stało z wyrażeniem 2. Po prostu to zalotłem.
John K
7
Co za cholera? Właśnie to odkryłem, zaraz po aktualizacji do PHP 7? Mógłbym używać tego od lat!
Buttle Butkus
TBH, dokumenty są poprawne. Stało się expr2tak, że po prostu zniknął i nie jest oceniany. $this->expensiveComputation() ?: "nope"nie jest identyczny z $this->expensiveComputation() ? $this->expensiveComputation() : "nope"- wyrażenie1 jest oceniane tylko raz.
Piskvor opuścił budynek
18

Uważaj na tablice. Następnie musimy napisać zmienną sprawdzającą ?, ponieważ:

  $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

Zaktualizowano

Z RFC. W przyszłości (w PHP 7) operator Null Coalesce Operator to zrobi, na przykład:

$param1 = $params['param1'] ?? null;
// Equivalent to:  $param1 = isset($params['param1']) ? $params['param1'] : null;
voodoo417
źródło
1
To nie odpowiada na pytanie, ani nie jest użyteczne dla nikogo, kto próbuje zrozumieć, kiedy użyć Elvis Operator.
Mark Amery
7
@Mark Amery hmm .. Naprawdę? Czy to nie jest pomocne? Czy naprawdę współpracowałeś z PHP i sprawdziłeś tysiące przypadków użycia dostępu do zmiennych tablicowych z trójek? Ok, zmieniłem tekst na „Uważaj na tablice ..”
voodoo417
więc zerowe połączenie i elvis są takie same?
Nabeel Khan,
7
@NabeelKhan Nie! To sprawia, że ​​operator Elvisa jest bezużyteczny w PHP imo. Operator Elvisa ocenia wyrażenie i jeśli jest prawdziwe, zwraca je, w przeciwnym razie zwraca ostatnią część. Ponieważ PHP jest słabo wpisane, wiele rzeczy będzie prawdą lub fałszem, a najprawdopodobniej nie będzie to, czego chcesz. Tj .: Chcesz ustawić wartość domyślną dla zmiennej, jeśli nie jest zdefiniowana, używając operatora Elvisa PHP powie, że 0 nie jest zdefiniowane, ale możesz chcieć tego 0 ... Dlatego PHP 7 otrzyma operator zerowej koalesce , Ściśle przetestuje zmienną pod kątem wartości null, więc PHP powie, że 0 nie jest niezdefiniowane.
Gregoire D.,
1
@FuscaSoftware: Używanie tego typu eliminacji błędów nie jest dobrym pomysłem z mojego doświadczenia.
TeeHays,
8

Kolejna ważna kwestia: Operator Elvisa przerywa proces tokenizacji Zend Opcache. Znalazłem to na własnej skórze! Chociaż można to naprawić w późniejszych wersjach, mogę potwierdzić, że ten problem występuje w PHP 5.5.38 (z wbudowanym Zend Opcache v7.0.6-dev).

Jeśli okaże się, że niektóre pliki „odmawiają” buforowania w Zend Opcache, może to być jeden z powodów ... Mam nadzieję, że to pomaga!

Prasad Paradkar
źródło
4

Tak, to nowość w PHP 5.3. Zwraca wartość wyrażenia testowego, jeśli jest ono oceniane jako PRAWDA, lub wartość alternatywną, jeśli jest oceniane jako FAŁSZ.

Atli
źródło
2
Subtelnie źle / wprowadzające w błąd; żaden operand nie musi być wartością logiczną. Liczy się to, czy pierwsza wartość jest prawdziwa , a nie czy to TRUE.
Mark Amery
@MarkAmery wyjaśnione. Powinny być dość trudne do błędnej interpretacji w ten sposób.
Atli