Может кто-нибудь объяснить разницу между кратким оператором shorthand ( ?:
) и оператором объединения нулей ( ??
) в PHP?
Когда они ведут себя по-разному и когда одинаково (если это вообще происходит)?
$a ?: $b
VS.
$a ?? $b
Может кто-нибудь объяснить разницу между кратким оператором shorthand ( ?:
) и оператором объединения нулей ( ??
) в PHP?
Когда они ведут себя по-разному и когда одинаково (если это вообще происходит)?
$a ?: $b
VS.
$a ?? $b
Когда ваш первый аргумент равен нулю, они в основном совпадают, за исключением того, что объединение с нулем не будет выводить, E_NOTICE
когда у вас есть неопределенная переменная. Документация по миграции на PHP 7.0 имеет следующее:
Нулевой оператор объединения (??) был добавлен в качестве синтаксического сахара для общего случая необходимости использования троичного в сочетании с isset (). Он возвращает свой первый операнд, если он существует и не равен NULL; в противном случае он возвращает свой второй операнд.
Вот пример кода, чтобы продемонстрировать это:
<?php
$a = null;
print $a ?? 'b'; // b
print "\n";
print $a ?: 'b'; // b
print "\n";
print $c ?? 'a'; // a
print "\n";
print $c ?: 'a'; // Notice: Undefined variable: c in /in/apAIb on line 14
print "\n";
$b = array('a' => null);
print $b['a'] ?? 'd'; // d
print "\n";
print $b['a'] ?: 'd'; // d
print "\n";
print $b['c'] ?? 'e'; // e
print "\n";
print $b['c'] ?: 'e'; // Notice: Undefined index: c in /in/apAIb on line 33
print "\n";
Линии, которые имеют уведомление, - это те, где я использую сокращенный тернарный оператор, а не оператор объединения нулей. Тем не менее, даже с уведомлением, PHP даст тот же ответ обратно.
Выполните код: https://3v4l.org/McavC
Конечно, это всегда предполагает первый аргумент null
. Как только он перестанет иметь значение null, вы получите различия в том, что ??
оператор всегда будет возвращать первый аргумент, тогда как ?:
сокращение будет только в том случае, если первый аргумент верен, и это зависит от того, как PHP будет приводить типы к булевому значению .
Так:
$a = false ?? 'f'; // false
$b = false ?: 'g'; // 'g'
тогда $a
будет равно false
и $b
равно 'g'
.
$b = []; var_dump($b['a']['b']['c'] ?? 'default');
или с объектами$b = new Foo; var_dump($b->a()->b()->c() ?? 'default');
$a = [];
. См .: 3v4l.org/iCCa0Запустил ниже на php интерактивный режим (
php -a
на терминале). Комментарий в каждой строке показывает результат.Итак, это моя интерпретация:
1. Нулевой оператор слияния -
??
:??
это как "ворота", которые пропускают только NULL .NULL
.??
же, как( !isset() || is_null() )
2. Тернарный оператор -
?:
?:
это как ворота, которые пропускаютanything falsy
- в том числеNULL
0
,empty string
,NULL
,false
,!isset()
,empty()
.. все , что пахнет falsyecho ($x ? $x : false)
?:
будет выбрасыватьPHP NOTICE
неопределенные (unset
или!isset()
) переменные3. Так доктор, когда я использую
??
и?:
..?:
когдаempty($x)
проверки!empty($x) ? $x : $y
может быть сокращена до$x ?: $y
if(!$x) { fn($x); } else { fn($y); }
можно сократить доfn(($x ?: $y))
??
когда!isset() || is_null()
проверку$object = $object ?? new objClassName();
4. Штабелирование операторов ...
Тройной Оператор может быть сложен ...
Источник и кредит для этого кода
Это в основном последовательность:
Нулевой Coalese Оператор может быть сложен ...
Это последовательность:
Используя укладку, я могу сократить это:
К этому:
Круто, верно? :-)
источник
Если вы используете ярлык тернарный оператор, как это, это вызовет уведомление, если
$_GET['username']
не установлен:Поэтому вместо этого вы должны сделать что-то вроде этого:
Оператор нулевой коалесцирующий эквивалентно выше заявление, и будет возвращать « по умолчанию» , если
$_GET['username']
не установлен илиnull
:Обратите внимание, что это не проверяет правдивость . Он проверяет, только если он установлен, а не ноль.
Вы также можете сделать это, и первое определенное (установленное и не
null
) значение будет возвращено:Теперь это правильный оператор объединения.
источник
Основное отличие состоит в том, что
Троичной Оператор выражение
expr1 ?: expr3
возвращает ,expr1
если имеетexpr1
значение ,TRUE
но с другой стороны Null Коалесцентного Оператором выражение(expr1) ?? (expr2)
принимает значение ,expr1
еслиexpr1
является неNULL
Тернарный оператор
expr1 ?: expr3
выдает уведомление, если левое значение(expr1)
не существует, но, с другой стороны, Null Coalescing Operator(expr1) ?? (expr2)
В частности, не выдает уведомление, если левое значение(expr1)
не существует, как, напримерisset()
.TernaryOperator остается ассоциативным
Нулевой оператор слияния является ассоциативным справа
Теперь давайте объясним разницу между примерами:
Троичный оператор
(?:)
Нулевой оператор объединения
(??)
Вот таблица, которая объясняет разницу и сходство между
'??'
и?:
источник
Оба они ведут себя по-разному, когда дело доходит до динамической обработки данных.
Если переменная пуста (''), объединение с нулем будет обрабатывать переменную как true, но сокращенный троичный оператор не будет. И это то, что нужно иметь в виду.
И вывод:
Ссылка: https://3v4l.org/ZBAa1
источник
It returns its first operand if it exists and is not NULL; otherwise it returns its second operand
.Оба являются сокращениями для более длинных выражений.
?:
это сокращение от$a ? $a : $b
. Это выражение будет иметь значение $ a, если $ a равно TRUE .??
это сокращение отisset($a) ? $a : $b
. Это выражение будет иметь значение $ a, если $ a установлено и не равно нулю.Их варианты использования перекрываются, когда $ a не определено или равно нулю. Если $ a
??
не определено, E_NOTICE не будет получен, но результаты будут такими же. Когда $ a равно нулю, результат тот же.источник
Для начинающих:
Нулевой оператор объединения (??)
Все верно, кроме
null
значений и неопределенных (переменная / индекс массива / атрибуты объекта)например:
это в основном проверка, что переменная (индекс массива, атрибут объекта и т. д.) существует, а не существует
null
. похоже наisset
функциюСокращенное обозначение троичного оператора (? :)
каждые ложные вещи (
false
,null
,0
, пустая строка) пришли как ложные, но если это не определено также приходят как ложные , ноNotice
выброситбывший
Надеюсь это поможет
источник
Прокрутите вниз по этой ссылке и просмотрите раздел, он дает вам сравнительный пример, как показано ниже:
Однако не рекомендуется объединять операторы в цепочку, так как это усложняет понимание кода при последующем его чтении.
По сути, использование оператора объединения делает его автоматической проверкой на нуль в отличие от троичного оператора.
источник
a || b || c
шаблон в JS, за исключением того, что PHP можно использовать для логических значений (false || 2
в JS - 2;false ?? 2
в PHP - false)Другие ответы идут глубоко и дают большие объяснения. Для тех, кто ищет быстрый ответ,
$a ?: 'fallback'
является$a ? $a : 'fallback'
пока
$a ?? 'fallback'
является$a = isset($a) ? $a : 'fallback'
Основное отличие будет в том случае, если левый оператор либо:
0
,''
,false
,[]
, ...)источник
$a =
в приведенном выше расширении??
.$a ?? 'fallback'
не устанавливает и не изменяет значение $ a. (Он просто возвращает значение).Кажется , есть свои плюсы и минусы использования либо
??
или?:
. Преимущество использования?:
состоит в том, что он оценивает false и null и "" то же самое. Дело в том, что он сообщает E_NOTICE, если предыдущий аргумент равен нулю. С??
профи, что нет E_NOTICE, но мошенник в том , что она не оценивает ложные и нуль то же самое. Исходя из моего опыта, я видел, как люди начинают взаимозаменяемо использовать null и false, но затем они в конечном итоге прибегают к модификации своего кода в соответствии с использованием либо null, либо false, но не обоих. Альтернативой является создание более сложного троичного условия(isset($something) or !$something) ? $something : $something_else
.Ниже приведен пример различия использования
??
оператора, использующего как null, так и false:Однако, развивая троичный оператор, мы можем заставить ложную или пустую строку "" вести себя так, как если бы она была нулевой, не бросая e_notice:
Лично я думаю, что было бы очень хорошо, если бы будущая версия PHP включала еще один новый оператор: он
:?
заменил приведенный выше синтаксис. то есть:// $var = $false :? "true";
тот синтаксис будет оценивать нуль, ложь и "" одинаково и не выбрасывать E_NOTICE ...источник
?? null ?:
вещь довольно крутая, спасибо, мистер. умный пареньисточник
Null Coalescing operator
выполняет только две задачи: проверяетwhether the variable is set
иwhether it is null
. Посмотрите на следующий пример:В приведенном выше примере кода указывается, что
Null Coalescing operator
обрабатывает несуществующую переменную и переменную, для которой установленоNULL
одинаковое значение.Null Coalescing operator
это улучшение по сравнению сternary operator
. Взгляните на следующий фрагмент кода, сравнивая их:Таким образом, разница между ними заключается в том, что
Null Coalescing operator
оператор предназначен для обработки неопределенных переменных лучше, чемternary operator
. Принимая во внимание, чтоternary operator
это сокращение дляif-else
.Null Coalescing operator
не предназначен для заменыternary operator
, но в некоторых случаях, например, в приведенном выше примере, он позволяет писать чистый код с меньшими хлопотами.Кредиты: http://dwellupper.io/post/6/php7-null-coalescing-operator-usage-and-examples
источник
isset($_POST['fullname'])
уже проверяетNULL
значения - так что&& !is_null($_POST['fullname'])
в первом примере все равно избыточноПри использовании суперглобальных объектов, таких как $ _GET или $ _REQUEST, вы должны знать, что они могут быть пустой строкой. В этом конкретном случае этот пример
потерпит неудачу, потому что значение $ username теперь является пустой строкой.
Поэтому при использовании $ _GET или даже $ _REQUEST вы должны использовать вместо этого троичный оператор, например:
Теперь значение $ username равно «nobody», как и ожидалось.
источник