Como uso o operador ternário (? :) no PHP como uma abreviação para “if / else”?

118

Com base nos exemplos desta página , tenho os exemplos de código funcional e não funcional abaixo.

Código de trabalho usando ifdeclaração:

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

Código não funcional usando operador ternário:

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

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

ATUALIZAÇÃO
Após a dica de Brian, descobri que as $testsaídas ecoando são o resultado esperado. O seguinte funciona como um encanto!

echo (empty($storeData['street2'])) ? 'Yes <br />' : 'No <br />';
Steven
fonte
4
Parece correto. Você já tentou echo $ test ;?
Brian Fisher,
Sua pergunta está enganando alguns voluntários e pesquisadores porque você não está escrevendo uma tarefa usando uma expressão ternária abreviada (não há "Operador de Elvis") - você está escrevendo uma expressão ternária abreviada. A diferença é que você está declarando ambos os valores retornados dependendo da avaliação. Em uma avaliação resumida, se o valor de entrada for "verdadeiro", ele será retornado; se for "falsey", o valor de fallback é retornado (este é o valor declarado após o Operador Elvis). Também há uma implementação visivelmente pobre do Null Coalescing Operator aqui também.
mickmackusa,

Respostas:

234

o

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

a sintaxe não é um operador "abreviação se" ( ?é chamado de operador condicional) porque você não pode executar o código da mesma maneira que faria:

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

Em seu exemplo, você está executando a echoinstrução quando o $addressnão está vazio. Você não pode fazer isso da mesma forma com o operador condicional. O que você pode fazer, no entanto, é echoo resultado do operador condicional:

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

e isso exibirá "A rua está vazia!" se estiver vazio, caso contrário, exibirá o endereço street2.

John Rasch
fonte
É a diferença entre afirmação e expressão
pmiranda
2
qual é a abreviação de novo? condition ?: falseque avalia conditionse é verdade?
oldboy
44

PHP 7

A partir do PHP 7, essa tarefa pode ser realizada simplesmente usando o operador Null coalescing como este:

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

Rabin Lama Dong
fonte
3
Apenas FYI, se $address['street2']é uma string vazia. Ele vai aceitar e não vai voltar 'Empty'. isset() != empty(). Isso só funcionará se o valor fornull
AFwcxx
Bem, eu estava apenas dando um exemplo. Mas eu modifiquei o código. Obrigado !
Rabin Lama Dong
2
Qual é a saída se $address['street2']não estiver vazia?
AliN11
Se $ address ['street2'] não estiver vazio, ele irá mostrar alguma forma de “true”. A forma usual do acima é mais parecida com: echo $address['street2'] ?? 'Empty';entretanto, como mencionado, é o “ operador de coalescência nulo ”, portanto, testa apenas para nulo e não vazio. Isto é porque ?? É efetivamente uma abreviação de isset ().
Brian C de
1
Conectado apenas para votar contra esta resposta. Isso não faz nada do que é anunciado.
TKoL
28

Declaração básica verdadeira / falsa

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

Mensagem de boas-vindas condicional

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

Mensagem de itens condicionais

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

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

Arun Yokesh
fonte
2
você o obteve no site de short hand e nem mesmo fez referência a ele
Richard
1
@Richard adicionou referências
Arun Yokesh
É isso ? No contexto do StackOverflow é sempre uma linha tênue, quero dizer, o Q pediu alguma coisa, não conseguiu encontrar por si mesmo, e então outra pessoa entregou esse conteúdo. É injusto copiar o conteúdo existente se ajudar e agregar valor a esta pergunta / resposta? Acho que as respostas no StackOverflow não são "seu próprio conteúdo" ... hmmm
Sliq
O primeiro exemplo está incorreto. O )está fora do lugar. Deve preceder o ?. A declaração completa deve ser$is_admin = ($user['permissions'] == 'admin') ? true : false;
1934286
12

O operador ternário é apenas uma abreviatura para bloco if / else. Seu código de trabalho não tem outra condição, portanto, não é adequado para isso.

O seguinte exemplo funcionará:

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

É o operador Ternário, também conhecido como operador Elvis (google it: P) que você está procurando.

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

Ele retorna o valor da variável ou padrão se a variável estiver vazia.

Ninja teclado
fonte
@Estruído, não posso discordar do que você diz, mas pesquisar isso no Google dará o resultado adequado e é um termo mais fácil de lembrar
Teclado ninja
4

Observe que, ao usar operadores condicionais aninhados, você pode querer usar parênteses para evitar possíveis problemas!

Parece que o PHP não funciona da mesma maneira que pelo menos Javascript ou 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');

O mesmo código em Javascript e C # retorna "Excepcional" em ambos os casos.

No segundo caso, o que o PHP faz é (ou pelo menos é o que eu entendo):

  1. é $score > 10? sim
  2. é $age > 10? não, então o atual $age > 10 ? 'Average' : 'Exceptional'retorna 'Excepcional'
  3. então, em vez de apenas parar a declaração inteira e retornar 'Excepcional', ele continua avaliando a próxima declaração
  4. a próxima declaração se torna a 'Exceptional' ? 'Horrible' : 'Average'que retorna 'Horrível', pois 'Excepcional' é verdade

Da documentação: http://php.net/manual/en/language.operators.comparison.php

É recomendado que você evite "empilhar" expressões ternárias. O comportamento do PHP ao usar mais de um operador ternário em uma única instrução não é óbvio.

user276648
fonte
3

Caminho rápido e curto:

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

Aqui estão alguns exemplos interessantes, com uma ou mais condições variadas.

$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>";
Aprendendo e compartilhando
fonte
2

Mensagem de boas-vindas condicional

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

Abreviação de PHP aninhada

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

Você pode fazer isso ainda mais curto, substituindo echopor<?= code ?>

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

Isso é útil especialmente quando você deseja determinar, dentro de uma barra de navegação, se a opção do menu deve ser exibida como já visitada (clicada) ou não:

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

Pathros
fonte
() São necessários nesse <? =?> Método?
curls
0

Acho que você usou os colchetes da maneira errada. Experimente isto:

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

Acho que deve funcionar, você também pode usar:

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

Eu acho que você provavelmente não deve usar o operador ternário no php. Considere o próximo exemplo:

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

Como você acha que $avariável conterá? (dica: dos) E permanecerá o mesmo mesmo se a $foovariável for atribuída a 2.

Para melhorar as coisas, você deve se recusar a usar este operador ou cercar a parte direita com colchetes da seguinte maneira:

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

Operador ternário é basicamente um atalho para a instrução if / else. Podemos usar para reduzir algumas linhas de código e aumentar a legibilidade.

Seu código parece mais limpo para mim. Mas podemos adicionar uma maneira mais limpa da seguinte maneira-

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

Outra maneira-

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

Observação: adicionei colchetes a toda a expressão para torná-la mais limpa. Costumava fazer isso para aumentar a legibilidade. Com o PHP7 podemos usar o Null Coalescing Operator / php 7 ?? operador para uma melhor abordagem. Mas sua exigência não se encaixa.

Exceção
fonte
-1

Também há um operador ternário abreviado e se parece com isto:

(expression1)?: expression2 retornará expression1 se for avaliada como true ou expression2 caso contrário.

Exemplo:

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

retornará

Apples are great!

Desde o PHP 5.3, é possível deixar de fora a parte intermediária do operador ternário. Expressão expr1?: Expr3 retorna expr1 se expr1 for avaliada como TRUE, e expr3 caso contrário.

Do Manual do PHP

horas_ro
fonte