Can someone explain the differences between ternary operator shorthand (?:
) and null coalescing operator (??
) in PHP?
When do they behave differently and when in the same way (if that even happens)?
$a ?: $b
VS.
$a ?? $b
The ternary operator is the only operator in PHP which requires three operands: the condition, the true and the false result.
Ternary Operator checks whether the value is true, but Null coalescing operator checks if the value is not null. If there is more iteration to be executed, null coalescing operator found to be faster than the ternary operator. Null coalescing operator gives better readability as well comparatively.
operator is known as Null-coalescing operator. It will return the value of its left-hand operand if it is not null. If it is null, then it will evaluate the right-hand operand and returns its result. Or if the left-hand operand evaluates to non-null, then it does not evaluate its right-hand operand.
The nullish coalescing operator ( ?? ) is a logical operator that returns its right-hand side operand when its left-hand side operand is null or undefined , and otherwise returns its left-hand side operand.
When your first argument is null, they're basically the same except that the null coalescing won't output an E_NOTICE
when you have an undefined variable. The PHP 7.0 migration docs has this to say:
The null coalescing operator (??) has been added as syntactic sugar for the common case of needing to use a ternary in conjunction with isset(). It returns its first operand if it exists and is not NULL; otherwise it returns its second operand.
Here's some example code to demonstrate this:
<?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";
The lines that have the notice are the ones where I'm using the shorthand ternary operator as opposed to the null coalescing operator. However, even with the notice, PHP will give the same response back.
Execute the code: https://3v4l.org/McavC
Of course, this is always assuming the first argument is null
. Once it's no longer null, then you end up with differences in that the ??
operator would always return the first argument while the ?:
shorthand would only if the first argument was truthy, and that relies on how PHP would type-cast things to a boolean.
So:
$a = false ?? 'f'; // false $b = false ?: 'g'; // 'g'
would then have $a
be equal to false
and $b
equal to 'g'
.
Ran the below on php interactive mode (php -a
on terminal). The comment on each line shows the result.
var_export (false ?? 'value2'); // false var_export (true ?? 'value2'); // true var_export (null ?? 'value2'); // value2 var_export ('' ?? 'value2'); // "" var_export (0 ?? 'value2'); // 0 var_export (false ?: 'value2'); // value2 var_export (true ?: 'value2'); // true var_export (null ?: 'value2'); // value2 var_export ('' ?: 'value2'); // value2 var_export (0 ?: 'value2'); // value2
??
??
is like a "gate" that only lets NULL through.NULL
.??
is same as ( !isset() || is_null() )
??
!isset() || is_null()
check$object = $object ?? new objClassName();
$v = $x ?? $y ?? $z; // This is a sequence of "SET && NOT NULL"s: if( $x && !is_null($x) ){ return $x; } else if( $y && !is_null($y) ){ return $y; } else { return $z; }
?:
?:
is like a gate that lets anything falsy
through - including NULL
0
, empty string
, NULL
, false
, !isset()
, empty()
X ? Y : Z
?:
will throw PHP NOTICE
on undefined (unset
or !isset()
) variables?:
empty()
, !isset()
, is_null()
etc!empty($x) ? $x : $y
to $x ?: $y
if(!$x) { echo $x; } else { echo $y; }
to echo $x ?: $y
echo 0 ?: 1 ?: 2 ?: 3; //1 echo 1 ?: 0 ?: 3 ?: 2; //1 echo 2 ?: 1 ?: 0 ?: 3; //2 echo 3 ?: 2 ?: 1 ?: 0; //3 echo 0 ?: 1 ?: 2 ?: 3; //1 echo 0 ?: 0 ?: 2 ?: 3; //2 echo 0 ?: 0 ?: 0 ?: 3; //3 // Source & Credit: http://php.net/manual/en/language.operators.comparison.php#95997 // This is basically a sequence of: if( truthy ) {} else if(truthy ) {} else if(truthy ) {} .. else {}
if( isset($_GET['name']) && !is_null($_GET['name'])) { $name = $_GET['name']; } else if( !empty($user_name) ) { $name = $user_name; } else { $name = 'anonymous'; }
$name = $_GET['name'] ?? $user_name ?: 'anonymous';
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With