Come si usa l'operatore ternario (? :) in PHP come abbreviazione di "if / else"?


118

Sulla base degli esempi di questa pagina , ho gli esempi di codice funzionanti e non funzionanti di seguito.

Codice funzionante utilizzando l' ifistruzione:

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

Codice non funzionante che utilizza l'operatore ternario:

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

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

AGGIORNAMENTO
Dopo il suggerimento di Brian, ho scoperto che l'eco $testproduce il risultato atteso. Quanto segue funziona come un fascino!

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

4
Sembra corretto. Hai provato ad echo $ test ;?
Brian Fisher

La tua domanda sta ingannando alcuni volontari e ricercatori perché non stai scrivendo un compito usando un'espressione stenaria ternaria (non c'è "Operatore Elvis") - stai scrivendo un'espressione ternaria a mano lunga. La differenza è che stai dichiarando entrambi i valori restituiti a seconda della valutazione. In una valutazione stenografica, se il valore di input è "true", viene restituito; se è "falsey", viene restituito il valore di fallback (questo è il valore dichiarato dopo l'operatore Elvis). Anche qui c'è un'implementazione notevolmente scarsa del Null Coalescing Operator.
mickmackusa

Risposte:


234

Il

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

la sintassi non è un operatore "abbreviato se" ( ?è chiamato operatore condizionale) perché non puoi eseguire il codice nello stesso modo in cui lo facessi:

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

Nel tuo esempio, stai eseguendo l' echoistruzione quando $addressnon è vuoto. Non puoi farlo allo stesso modo con l'operatore condizionale. Quello che puoi fare, tuttavia, è echoil risultato dell'operatore condizionale:

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

e questo mostrerà "Street is empty!" se è vuoto, altrimenti visualizzerà l'indirizzo street2.


È la differenza tra dichiarazione ed espressione
pmiranda

2
qual è di nuovo la stenografia? condition ?: falseche valuta conditionse è vero?
oldboy

44

PHP 7+

A partire da PHP 7, questa attività può essere eseguita semplicemente utilizzando l' operatore di coalescenza Null in questo modo:

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


3
Solo per tua informazione, se $address['street2']è una stringa vuota. Lo accetterà e non tornerà 'Empty'. isset() != empty(). null
Funzionerà

Bene, stavo solo fornendo un esempio. Ma ho modificato il codice. Grazie !
Rabin Lama Dong

2
Qual è l'output se $address['street2']non è vuoto?
AliN11

Se $ address ['street2'] non è vuoto, produrrà una qualche forma di "true". La forma usuale di quanto sopra è più simile: echo $address['street2'] ?? 'Empty';tuttavia, come accennato, è l '" operatore di coalescenza nullo " quindi verifica solo null e non vuoto. Questo è perché ?? È effettivamente una scorciatoia per isset ().
Brian C

1
Accesso eseguito solo per downvote questa risposta. Questo non fa affatto ciò che viene pubblicizzato.
TKoL

28

Dichiarazione di base vero / falso

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

Messaggio di benvenuto condizionale

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

Messaggio di elementi condizionali

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

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


2
l'hai preso dal sito web di short hand e non lo hai nemmeno fatto riferimento
Richard

1
@Richard ha aggiunto riferimenti
Arun Yokesh

È ? Nel contesto di StackOverflow è sempre una linea sottile, voglio dire che il Q ha chiesto qualcosa, incapace di trovarlo da solo, e poi qualcun altro ha consegnato questo contenuto. È ingiusto copiare il contenuto esistente se aiuta e aggiunge valore a questa domanda / risposta? Penso che le risposte su StackOverflow non siano "il tuo contenuto" ... hmmm
Sliq

Il primo esempio non è corretto. Il )è fuori luogo. Dovrebbe precedere il file ?. La dichiarazione completa dovrebbe essere$is_admin = ($user['permissions'] == 'admin') ? true : false;
1934286

12

L'operatore ternario è solo una scorciatoia per e if / else block. Il tuo codice di lavoro non ha un'altra condizione, quindi non è adatto a questo.

Il seguente esempio funzionerà:

echo empty($address['street2']) ? 'empty' : 'not empty';

6

È l'operatore ternario aka operatore Elvis (google it: P) che stai cercando.

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

Restituisce il valore della variabile o predefinito se la variabile è vuota.


@Structed Non posso essere in disaccordo con quello che dici ma, cercare su Google questo ti darà il risultato migliore ed è un termine più facile da ricordare
Ninja della tastiera

4

Nota che quando usi operatori condizionali annidati, potresti voler usare le parentesi per evitare possibili problemi!

Sembra che PHP non funzioni allo stesso modo almeno di Javascript o 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');

Lo stesso codice in Javascript e C # restituisce "Eccezionale" in entrambi i casi.

Nel secondo caso, quello che fa PHP è (o almeno questo è quello che ho capito):

  1. è $score > 10? sì
  2. è $age > 10? no, quindi l'attuale $age > 10 ? 'Average' : 'Exceptional'restituisce "Eccezionale"
  3. quindi, invece di fermare l'intera istruzione e restituire "Eccezionale", continua a valutare l'istruzione successiva
  4. l'affermazione successiva diventa 'Exceptional' ? 'Horrible' : 'Average'che restituisce "Orribile", poiché "Eccezionale" è veritiero

Dalla documentazione: http://php.net/manual/en/language.operators.comparison.php

Si consiglia di evitare di "impilare" espressioni ternarie. Il comportamento di PHP quando si utilizza più di un operatore ternario all'interno di una singola istruzione non è ovvio.


3

Modo rapido e breve:

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

Ecco alcuni esempi interessanti, con una o più condizioni diverse.

$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>";

2

Messaggio di benvenuto condizionale

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

Stenografia PHP annidata

echo 'Your score is:  '.($score > 10 ? ($age > 10 ? 'Average' : 'Exceptional') : ($age > 10 ? 'Horrible' : 'Average') );

2

Puoi farlo ancora più breve sostituendo echocon<?= code ?>

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

Ciò è utile soprattutto quando si desidera determinare, all'interno di una barra di navigazione, se l'opzione di menu deve essere visualizzata come già visitata (cliccata) o meno:

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


Le () sono necessarie in quel metodo <? =?>?
riccioli

0

Penso che tu abbia usato le parentesi nel modo sbagliato. Prova questo:

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

Penso che dovrebbe funzionare, puoi anche usare:

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

0

Penso che probabilmente non dovresti usare l'operatore ternario in php. Considera il prossimo esempio:

<?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);

Come pensi, quale $avariabile conterrà? (suggerimento: dos) E rimarrà lo stesso anche se la $foovariabile sarà assegnata a 2.

Per migliorare le cose dovresti rifiutarti di usare questo operatore o circondare la parte destra con parentesi graffe nel modo seguente:

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

0

L'operatore ternario è fondamentalmente una scorciatoia per l'istruzione if / else. Possiamo utilizzare per ridurre poche righe di codice e aumentare la leggibilità.

Il tuo codice mi sembra più pulito. Ma possiamo aggiungere un modo più pulito come segue-

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

Un altro modo-

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

Nota: ho aggiunto parentesi a tutta l'espressione per renderla più pulita. Di solito lo facevo per aumentare la leggibilità. Con PHP7 possiamo usare Null Coalescing Operator / php 7 ?? operatore per un migliore approccio. Ma la tua esigenza non si adatta.


-1

C'è anche un operatore ternario stenografico e assomiglia a questo:

(espressione1)?: espressione2 restituirà espressione1 se restituisce true o altrimenti espressione2 .

Esempio:

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

sarà di ritorno

Apples are great!

A partire da PHP 5.3, è possibile tralasciare la parte centrale dell'operatore ternario. Expression expr1?: Expr3 restituisce expr1 se expr1 restituisce TRUE e expr3 in caso contrario.

Dal manuale PHP

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.