?: оператор ( "оператор Элвиса" ) в PHP

Я видел это сегодня в некотором PHP-коде:

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

Я не знаком с оператором ?:, который используется здесь. Он выглядит как тернарный оператор, но выражение для оценки, если предикат является истинным, опущено. Что это значит?

Ответ 1

Он вычисляет левый операнд, если левый операнд правша и правый операнд в противном случае.

В псевдокоде

foo = bar ?: baz;

грубо разрешается

foo = bar ? bar : baz;

или

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

с той разницей, что bar будет оцениваться только один раз.

Вы также можете использовать это, чтобы выполнить "самопроверку" foo, как показано в приведенном вами примере кода:

foo = foo ?: bar;

Это назначит bar foo, если foo имеет значение null или false, иначе он оставит 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'
?>
Кстати, он назывался Elvis operator.

Elvis operator

Ответ 2

Смотрите документы:

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

Ответ 3

Будьте осторожны с массивами. Мы должны написать контрольную переменную после ?, потому что:

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

Ответ 4

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

Если вы обнаружите, что некоторые из ваших файлов "отказываются" кэшироваться в Zend Opcache, это может быть одной из причин... Надеюсь, это поможет!

Ответ 5

Да, это новое в PHP 5.3. Он возвращает либо значение тестового выражения, если оно оценивается как TRUE, либо альтернативное значение, если оно оценивается как FALSE.

Ответ 6

Я думал, что это потому, что Элвис вышел из комнаты и, следовательно, не там.