Jak używać operatora trójargumentowego (?:) W PHP jako skrótu dla „if / else”?

118

Na podstawie przykładów z tej strony poniżej mam działające i niedziałające próbki kodu.

Kod roboczy przy użyciu ifinstrukcji:

if (!empty($address['street2'])) echo $address['street2'].'<br />';

Niedziałający kod wykorzystujący operator trójskładnikowy:

$test = (empty($address['street2'])) ? 'Yes <br />' : 'No <br />';

// Also tested this
(empty($address['street2'])) ? 'Yes <br />' : 'No <br />';

AKTUALIZACJA
Po wskazówce Briana stwierdziłem, że echo $testdaje oczekiwany rezultat. Poniższe działa jak urok!

echo (empty($storeData['street2'])) ? 'Yes <br />' : 'No <br />';
Steven
źródło
4
Wygląda poprawnie. Czy próbowałeś wykonać echo $ test ;?
Brian Fisher
Twoje pytanie oszukuje niektórych ochotników i badaczy, ponieważ nie piszesz zadania używając skróconego, trójskładnikowego wyrażenia (nie ma „Elvisa Operatora”) - piszesz odręczne trójskładnikowe wyrażenie. Różnica polega na tym, że deklarujesz obie zwrócone wartości w zależności od oceny. W skróconej ocenie, jeśli wartość wejściowa jest „zgodna z prawdą”, jest zwracana; jeśli jest to „falsey”, zwracana jest wartość rezerwowa (jest to wartość zadeklarowana po operatorze Elvisa). Występuje również zauważalnie słaba implementacja Null Coalescing Operator.
mickmackusa

Odpowiedzi:

234

Plik

(condition) ? /* value to return if condition is true */ 
            : /* value to return if condition is false */ ;

składnia nie jest operatorem „skrótu, jeśli” ( ?nazywany jest operatorem warunkowym), ponieważ nie możesz wykonać kodu w taki sam sposób, jak gdybyś:

if (condition) {
    /* condition is true, do something like echo */
}
else {
    /* condition is false, do something else */
}

W twoim przykładzie wykonujesz echoinstrukcję, gdy $addressnie jest pusta. Nie możesz tego zrobić w ten sam sposób z operatorem warunkowym. To, co możesz jednak zrobić, jest echowynikiem działania operatora warunkowego:

echo empty($address['street2']) ? "Street2 is empty!" : $address['street2'];

a to wyświetli komunikat „Ulica jest pusta!” jeśli jest pusty, w przeciwnym razie wyświetli adres street2.

John Rasch
źródło
To różnica między stwierdzeniem a wyrażeniem
pmiranda
2
co to jest skrót? condition ?: falseco ocenia się, conditionjeśli jest to prawda?
oldboy
44

PHP 7+

Począwszy od PHP 7, to zadanie można wykonać po prostu za pomocą operatora koalescencji zerowej w następujący sposób:

echo !empty($address['street2']) ?? 'Empty';

Rabin Lama Dong
źródło
3
Po prostu do Twojej wiadomości, jeśli $address['street2']to pusty ciąg. Zaakceptuje to i nie wróci 'Empty'. isset() != empty(). To zadziała tylko wtedy, gdy wartość tonull
AFwcxx,
Cóż, podałem tylko przykład. Ale zmodyfikowałem kod. Dzięki !
Rabin Lama Dong
2
Jaki jest wynik, jeśli $address['street2']nie jest pusty?
AliN11
Jeśli $ address ['street2'] nie jest puste, wyświetli jakąś formę „true”. Zwykła forma powyższego jest bardziej podobna: echo $address['street2'] ?? 'Empty';jednak, jak wspomniano, jest to „ operator koalescencji zerowej ”, więc sprawdza tylko wartość null, a nie pustą. To dlatego, że ?? W rzeczywistości jest skrótem dla isset ().
Brian C
1
Zalogowano się tylko po to, aby zagłosować negatywnie na tę odpowiedź. To w ogóle nie robi tego, co jest reklamowane.
TKoL
28

Podstawowa deklaracja prawda / fałsz

$is_admin = ($user['permissions'] == 'admin' ? true : false);

Warunkowa wiadomość powitalna

echo 'Welcome '.($user['is_logged_in'] ? $user['first_name'] : 'Guest').'!';

Komunikat dotyczący elementów warunkowych

echo 'Your cart contains '.$num_items.' item'.($num_items != 1 ? 's' : '').'.';

ref: https://davidwalsh.name/php-ternary-examples

Arun Yokesh
źródło
2
masz go ze strony z krótkimi rozdaniami i nawet nie odwołałeś się do niego
Richard
1
@Richard dodał referencje
Arun Yokesh
Czy to jest? W kontekście StackOverflow zawsze jest to cienka kreska, to znaczy Q poprosił o coś, nie mogąc tego samodzielnie znaleźć, a potem ktoś inny dostarczył tę treść. Czy kopiowanie istniejących treści jest niesprawiedliwe, jeśli pomaga i dodaje wartości do tego pytania / odpowiedzi? Myślę, że odpowiedzi na StackOverflow nie są „twoją własną zawartością” ... hmmm
Sliq
Pierwszy przykład jest nieprawidłowy. )Jest niesłuszna. Powinien poprzedzać ?. Kompletne oświadczenie powinno być$is_admin = ($user['permissions'] == 'admin') ? true : false;
1934286
12

Operator trójskładnikowy jest po prostu skrótem dla bloku i if / else. Twój działający kod nie ma innego warunku, więc nie nadaje się do tego.

Poniższy przykład zadziała:

echo empty($address['street2']) ? 'empty' : 'not empty';
adrianbanks
źródło
6

To operator trójargumentowy aka operator Elvisa (google it: P), którego szukasz.

echo $address['street2'] ?: 'Empty'; 

Zwraca wartość zmiennej lub wartość domyślną, jeśli zmienna jest pusta.

Klawiatura ninja
źródło
@Structed Nie mogę się nie zgodzić z tym, co mówisz, ale wyszukanie tego w Google da ci odpowiedni wynik i łatwiej jest przypomnieć sobie
Klawiatura ninja,
4

Zwróć uwagę, że używając zagnieżdżonych operatorów warunkowych, możesz chcieć użyć nawiasów, aby uniknąć możliwych problemów!

Wygląda na to, że PHP nie działa tak samo, jak przynajmniej JavaScript lub C #.

$score = 15;
$age = 5;

// The following will return "Exceptional"
echo 'Your score is: ' . ($score > 10 ? ($age > 10 ? 'Average' : 'Exceptional') : ($age > 10 ? 'Horrible' : 'Average'));

// The following will return "Horrible"
echo 'Your score is: ' . ($score > 10 ? $age > 10 ? 'Average' : 'Exceptional' : $age > 10 ? 'Horrible' : 'Average');

Ten sam kod w JavaScript i C # zwraca „Wyjątkowe” w obu przypadkach.

W drugim przypadku to, co robi PHP (a przynajmniej to rozumiem):

  1. jest $score > 10? tak
  2. jest $age > 10? nie, więc bieżący $age > 10 ? 'Average' : 'Exceptional'zwraca „Wyjątkowy”
  3. następnie zamiast po prostu zatrzymać całą instrukcję i zwrócić „Wyjątkowy”, kontynuuje ocenę następnej instrukcji
  4. następne stwierdzenie 'Exceptional' ? 'Horrible' : 'Average'zwraca „Straszne”, ponieważ „Wyjątkowe” jest prawdziwe

Z dokumentacji: http://php.net/manual/en/language.operators.comparison.php

Zaleca się unikanie „układania” wyrażeń trójskładnikowych. Zachowanie PHP podczas używania więcej niż jednego operatora trójskładnikowego w jednej instrukcji nie jest oczywiste.

user276648
źródło
3

Szybka i krótka droga:

echo $address['street2'] ? : "No";

Oto kilka interesujących przykładów z jednym lub kilkoma różnymi warunkami.

$color = "blue";

// Condition #1 Show color without specifying variable 
echo $color ? : "Undefined";
echo "<br>";

// Condition #2
echo $color ? $color : "Undefined";
echo "<br>";

// Condition #3
echo ($color) ? $color : "Undefined";
echo "<br>";

// Condition #4
echo ($color == "blue") ? $color : "Undefined";
echo "<br>";

// Condition #5
echo ($color == "" ? $color : ($color == "blue" ? $color : "Undefined"));
echo "<br>";

// Condition #6
echo ($color == "blue" ? $color : ($color == "" ? $color : ($color == "" ? $color : "Undefined")));
echo "<br>";

// Condition #7
echo ($color != "") ? ($color != "" ? ($color == "blue" ? $color : "Undefined") : "Undefined") : "Undefined";
echo "<br>";
Uczenie się i dzielenie się
źródło
2

Warunkowa wiadomość powitalna

echo 'Welcome '.($user['is_logged_in'] ? $user['first_name'] : 'Guest').'!';

Zagnieżdżony skrót PHP

echo 'Your score is:  '.($score > 10 ? ($age > 10 ? 'Average' : 'Exceptional') : ($age > 10 ? 'Horrible' : 'Average') );
Adnan
źródło
2

Można to zrobić nawet krócej, zastępując echoz<?= code ?>

<?=(empty($storeData['street2'])) ? 'Yes <br />' : 'No <br />'?>

Jest to przydatne zwłaszcza, gdy chcesz określić w pasku nawigacyjnym, czy opcja menu ma być wyświetlana jako już odwiedzona (kliknięta), czy nie:

<li<?=($basename=='index.php' ? ' class="active"' : '')?>><a href="index.php">Home</a></li>

Pathros
źródło
Czy () jest potrzebne w tej metodzie <? =?>?
loki
0

Myślę, że użyłeś nawiasów w niewłaściwy sposób. Spróbuj tego:

$test = (empty($address['street2']) ? 'Yes <br />' : 'No <br />');

Myślę, że powinno działać, możesz też użyć:

echo (empty($address['street2']) ? 'Yes <br />' : 'No <br />');
user2909855
źródło
0

Myślę, że prawdopodobnie nie powinieneś używać operatora trójskładnikowego w php. Rozważ następny przykład:

<?php

function f1($n) {
    var_dump("first funct");
    return $n == 1;
}

function f2($n) {
    var_dump("second funct");
    return $n == 2;
}


$foo = 1;
$a = (f1($foo)) ? "uno" : (f2($foo)) ? "dos" : "tres";
print($a);

Jak myślisz, jaka $azmienna będzie zawierać? (wskazówka: dos) I pozostanie bez zmian, nawet jeśli $foozmienna zostanie przypisana do 2.

Aby było lepiej, należy odmówić użycia tego operatora lub otoczyć prawą część nawiasami klamrowymi w następujący sposób:

$a = (f1($foo)) ? "uno" : ((f2($foo)) ? "dos" : "tres");
rela589n
źródło
0

Operator trójargumentowy jest w zasadzie skrótem dla instrukcji if / else. Możemy użyć, aby zmniejszyć kilka wierszy kodu i zwiększyć czytelność.

Twój kod wydaje mi się czystszy. Ale możemy dodać bardziej przejrzysty sposób w następujący sposób:

$test = (empty($address['street2'])) ? 'Yes <br />' : 'No <br />';

Inny sposób-

$test = ((empty($address['street2'])) ? 'Yes <br />' : 'No <br />');

Uwaga - dodałem nawias do całego wyrażenia, aby było bardziej przejrzyste. Zwykle robiłem to, aby zwiększyć czytelność. Z PHP7 możemy użyć Null Coalescing Operator / php 7 ?? operator za lepsze podejście. Ale twoje wymaganie nie pasuje.

Wyjątek
źródło
-1

Istnieje również skrótowy operator trójskładnikowy i wygląda to tak:

(wyrażenie1)?: wyrażenie2 zwróci wyrażenie1, jeśli zwróci wartość true lub wyrażenie2 w przeciwnym razie.

Przykład:

$a = 'Apples';
echo ($a ?: 'Oranges') . ' are great!';

wróci

Apples are great!

Od PHP 5.3 można pominąć środkową część operatora trójskładnikowego. Wyrażenie wyrażenie1?: Wyrażenie3 zwraca wyrażenie1, jeśli wyrażenie1 ma wartość PRAWDA, a wyrażenie3 w przeciwnym razie.

Z podręcznika PHP

horas_ro
źródło