Как использовать тернарный оператор (?:) В PHP как сокращение для «if / else»?

118

Основываясь на примерах с этой страницы , у меня есть рабочие и нерабочие образцы кода ниже.

Рабочий код с использованием ifоператора:

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

Нерабочий код с использованием тернарного оператора:

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

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

ОБНОВЛЕНИЕ
После подсказки Брайана я обнаружил, что эхо $testдает ожидаемый результат. Следующее работает как шарм!

echo (empty($storeData['street2'])) ? 'Yes <br />' : 'No <br />';
Стивен
источник
4
Выглядит правильно. Вы пробовали echo $ test ;?
Брайан Фишер,
Ваш вопрос вводит в заблуждение некоторых добровольцев и исследователей, потому что вы пишете задание не с использованием сокращенного тернарного выражения ("Оператора Элвиса" не существует) - вы пишете полное тернарное выражение. Разница в том, что вы объявляете оба возвращаемых значения в зависимости от оценки. В сокращенной оценке, если входное значение «истинно», оно возвращается; если это "ложно", то возвращается резервное значение (это значение, объявленное после оператора Элвиса). Здесь также заметно плохая реализация оператора Null Coalescing.
mickmackusa

Ответы:

234

The

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

синтаксис не является сокращенным оператором if ( ?называется условным оператором), потому что вы не можете выполнить код таким же образом, как если бы вы это сделали:

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

В вашем примере вы выполняете echoинструкцию, когда $addressне пусто. Вы не можете сделать то же самое с условным оператором. Однако то, что вы можете сделать, является echoрезультатом условного оператора:

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

и это отобразит "Улица пуста!" если он пуст, в противном случае будет отображаться адрес street2.

Джон Раш
источник
В этом разница между утверждением и выражением
пмиранда
2
опять что за стенография? condition ?: falseкоторый оценивается, conditionесли это правда?
oldboy
44

PHP 7+

Начиная с PHP 7, эту задачу можно выполнить, просто используя оператор объединения Null, например:

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

Рабин Лама Донг
источник
3
Просто к сведению, если $address['street2']это пустая строка. Он примет это и не вернется 'Empty'. isset() != empty(), Это будет работать, только если значениеnull
AFwcxx
Ну, я просто привел пример. Но я изменил код. Спасибо !
Рабин Лама Донг
2
Что будет на выходе, если $address['street2']не пусто?
AliN11
Если $ address ['street2'] не пусто, он выдаст некоторую форму «true». Обычная форма вышеизложенного больше похожа: echo $address['street2'] ?? 'Empty';однако, как уже упоминалось, это « оператор объединения с нулевым значением », поэтому он проверяет только значение NULL, а не пустой. Это потому что ?? Фактически является сокращением для isset ().
Brian C
1
Вы вошли в систему, чтобы проголосовать против этого ответа. Это совсем не то, что рекламируется.
TKoL
28

Основное истинное / ложное объявление

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

Условное приветственное сообщение

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

Сообщение с условными элементами

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

ссылка: https://davidwalsh.name/php-ternary-examples

Арун Йокеш
источник
2
вы получили его с сайта коротких рук и даже не упомянули об этом
Ричард
1
@Richard добавил отсылки
Арун Йокеш
Это ? В контексте StackOverflow это всегда тонкая линия, я имею в виду, что Q что-то просил, но не смог найти сам, а затем кто-то другой доставил этот контент. Является ли несправедливым копирование существующего контента, если оно помогает и повышает ценность этого вопроса / ответа? Я думаю, что ответы на StackOverflow - это не «ваш собственный контент» ...
хммм
Первый пример неверен. )Неуместен. Он должен предшествовать ?. Полная выписка должна быть$is_admin = ($user['permissions'] == 'admin') ? true : false;
1934286
12

Тернарный оператор - это просто сокращение для блока if / else. В вашем рабочем коде нет условия else, поэтому он не подходит для этого.

Следующий пример будет работать:

echo empty($address['street2']) ? 'empty' : 'not empty';
adrianbanks
источник
6

Вы ищете тернарный оператор, он же оператор Элвиса (google it: P).

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

Он возвращает значение переменной или значение по умолчанию, если переменная пуста.

Клавиатура ниндзя
источник
@Structed Я не могу не согласиться с тем, что вы говорите, но поиск в Google даст вам правильный результат, и этот термин легче напомнить
Keyboard ninja
4

Обратите внимание, что при использовании вложенных условных операторов вы можете использовать круглые скобки, чтобы избежать возможных проблем!

Похоже, PHP работает не так, как хотя бы Javascript или 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');

Один и тот же код в Javascript и C # в обоих случаях возвращает «Исключительно».

Во втором случае PHP делает (или, по крайней мере, то, что я понимаю):

  1. есть $score > 10? да
  2. есть $age > 10? нет, поэтому текущий $age > 10 ? 'Average' : 'Exceptional'возвращает "Исключительно"
  3. затем, вместо того, чтобы просто останавливать весь оператор и возвращать «Исключительно», он продолжает вычислять следующий оператор.
  4. становится следующий оператор, 'Exceptional' ? 'Horrible' : 'Average'который возвращает «Ужасно», поскольку «Исключительно» истинно

Из документации: http://php.net/manual/en/language.operators.comparison.php

Рекомендуется избегать "складывания" тернарных выражений. Поведение PHP при использовании более чем одного тернарного оператора в одном операторе неочевидно.

user276648
источник
3

Быстрый и короткий путь:

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

Вот несколько интересных примеров с одним или несколькими различными условиями.

$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

Условное приветственное сообщение

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

Вложенная стенография PHP

echo 'Your score is:  '.($score > 10 ? ($age > 10 ? 'Average' : 'Exceptional') : ($age > 10 ? 'Horrible' : 'Average') );
Аднан
источник
2

Вы можете сделать это еще короче, заменив echoна<?= code ?>

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

Это полезно, особенно когда вы хотите определить внутри навигационной панели, должен ли пункт меню отображаться как уже посещенный (нажатый) или нет:

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

Пафрос
источник
Нужны ли () в этом методе <? =?>?
curls
0

Я думаю, вы неправильно использовали скобки. Попробуй это:

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

Думаю, должно работать, также можно использовать:

echo (empty($address['street2']) ? 'Yes <br />' : 'No <br />');
user2909855
источник
0

Я думаю, вам, вероятно, не следует использовать тернарный оператор в php. Рассмотрим следующий пример:

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

Как вы думаете, какая $aпеременная будет содержать? (подсказка: дос) И он останется прежним, даже если$foo переменной будет присвоено значение 2.

Чтобы все было лучше, вы должны либо отказаться от использования этого оператора, либо заключить правую часть в фигурные скобки следующим образом:

$a = (f1($foo)) ? "uno" : ((f2($foo)) ? "dos" : "tres");
rela589n
источник
0

Тернарный оператор - это в основном сокращение для оператора if / else. Мы можем использовать его, чтобы сократить количество строк кода и повысить удобочитаемость.

Мне ваш код кажется чище. Но мы можем добавить более чистый способ следующим образом:

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

По-другому-

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

Примечание. Я добавил скобки ко всему выражению, чтобы оно было чище. Обычно я делал это для повышения читабельности. С PHP7 мы можем использовать Null Coalescing Operator / php 7 ?? оператор для лучшего подхода. Но вашим требованиям это не подходит.

исключение
источник
-1

Также есть сокращенный тернарный оператор, который выглядит так:

(выражение1)?: выражение2 вернет выражение1, если оно оценивается как истина или выражение2 противном случае.

Пример:

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

вернется

Apples are great!

Начиная с PHP 5.3, можно опустить среднюю часть тернарного оператора. Выражение expr1?: Expr3 возвращает expr1, если expr1 имеет значение TRUE, и expr3 в противном случае.

Из руководства по PHP

horas_ro
источник