?: оператор ( "оператор Элвиса" ) в 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
Я думал, что это потому, что Элвис вышел из комнаты и, следовательно, не там.