?: оператор ("оператор Елвіса") в PHP


257

Я бачив це сьогодні в якомусь PHP-коді:

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

Я не знайомий з ?:оператором, який тут використовується. Він схожий на потрійний оператор, але вираз для оцінки того, чи є присудок істинним, пропущено. Що це означає?

Відповіді:


528

Він оцінює лівий операнд, якщо лівий операнд є правдоподібним , а правий операнд - інакше.

У псевдокоді

foo = bar ?: baz;

приблизно вирішує до

foo = bar ? bar : baz;

або

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

з тією різницею, яка barбуде оцінена лише один раз.

Ви також можете використовувати це для "самоперевірки", fooяк показано у прикладі коду, який ви опублікували:

foo = foo ?: bar;

Це буде призначати barв fooразі fooдорівнює нулю або falsey, інакше він залишить fooбез змін.

Ще кілька прикладів:

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

До речі, його називають оператором Елвіса .

Оператор Елвіса


11
Переконайтеся, що змінна в круглих дужках існує, хоча ви збираєтеся створити помилку. PHP не буде просто вважати, що він має значення nullабо щось інше.
Justinin

20
Цікаво, що ця відповідь утворює рекурсивний цикл із статті Wiki, яка не повністю пояснює, чому його називають "оператором Елвіса".
здається.забавляючи

41
Трохи менше операції, трохи більше вираження, будь ласка.
aalaap

2
Чому б просто не використовувати a ||. Так blah || 'default'?
Noitidart

10
@Noitidart Оскільки, на відміну від JS, де він повертає крайній лівий трибунний операнд, у PHP ||оператор завжди повертає булеву форму.
ksadowski

58

Дивіться документи :

Починаючи з PHP 5.3, можна залишати середню частину потрійного оператора. Вираз expr1 ?: expr3повертається, expr1якщо expr1оцінюється на TRUEта expr3інше.


10
Їм потрібен новий автор документа, оскільки неминуче хтось запитає, що сталося з expr2. Я просто заграю.
Джон К

7
Якого біса? Я просто зараз це дізнаюся, відразу після оновлення до PHP 7? Я міг би цим користуватися роками!
Buttle Butkus

TBH, документи є правильними. Що сталося, expr2це те, що він просто зник і не оцінюється. $this->expensiveComputation() ?: "nope"не ідентично $this->expensiveComputation() ? $this->expensiveComputation() : "nope"- expr1 оцінюється лише один раз.
Пісквор вийшов з будівлі

18

Будьте обережні з масивами. Ми повинні написати контрольну змінну після ?, тому що:

  $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

Оновлено

Від RFC. Надалі (у PHP 7) оператор Null Coalesce Operator зробить це, наприклад:

$param1 = $params['param1'] ?? null;
// Equivalent to:  $param1 = isset($params['param1']) ? $params['param1'] : null;

1
Це не дає відповіді на питання, а також не корисно для тих, хто намагається зрозуміти, коли користуватися оператором Elvis.
Марк Амері

7
@ Марк Амери Хм .. Дійсно? Хіба не корисно? Ви справді працювали з PHP і розглядали тисячі випадків використання дозволу на масиви масивів із потрійними? Гаразд, я змінив текст на "Будьте обережні з масивами .."
voodoo417,

так нульові злиття та елвіс однакові?
Набіель Хан

7
@NabeelKhan Ні! І це робить оператор Elvis свого роду марним у PHP imo. Оператор Elvis оцінює вираз, і якщо це правда, він повертає його ще, він повертає останню частину. Оскільки PHP низько набраний, багато речей буде істинними, або хибними, і, швидше за все, речі не будуть такими, якими ви хочете. Тобто: Ви хочете встановити значення змінної за замовчуванням для змінної, якщо вона не визначена, користуючись оператором Elvis PHP скаже, що 0 не визначено, але вам може знадобитися це 0 ... Ось чому PHP 7 отримає оператора Null Coalesce , Це суворо перевірить вашу змінну проти нуля, тому PHP скаже, що 0 не визначено.
Gregoire D.

1
@FuscaSoftware: Використання подібного способу придушення помилок не є хорошою ідеєю.
TeeHays

8

Ще одне важливе враження: Оператор Елвіса порушує процес токенізації Zend Opcache. Я знайшов це важким шляхом! Хоча це може бути виправлено в пізніших версіях, я можу підтвердити, що ця проблема існує в PHP 5.5.38 (із вбудованим Zend Opcache v7.0.6-dev).

Якщо ви виявите, що деякі ваші файли "відмовляються" від кешування в Zend Opcache, це може бути однією з причин ... Сподіваюся, це допомагає!


4

Так, це нове в PHP 5.3. Він повертає або значення тестового вираження, якщо воно оцінюється як ІСТИНА, або альтернативне значення, якщо воно оцінюється як ЛІЖНЕ.


2
Тонко неправильні / оманливі; жоден операнд не повинен бути булевим. Важливо, чи є перше значення правдою , а не чи є TRUE.
Марк Амері

@MarkAmery Уточнено. Слід досить важко неправильно трактувати це таким чином.
Атлі
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.