?: operator (the 'Elvis operator') in PHP
It evaluates to the left operand if the left operand is truthy, and the right operand otherwise.
In pseudocode,
foo = bar ?: baz;
roughly resolves to
foo = bar ? bar : baz;
or
if (bar) {
foo = bar;
} else {
foo = baz;
}
with the difference that bar
will only be evaluated once.
You can also use this to do a "self-check" of foo
as demonstrated in the code example you posted:
foo = foo ?: bar;
This will assign bar
to foo
if foo
is null or falsey, else it will leave foo
unchanged.
Some more examples:
<?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'
?>
By the way, it's called the Elvis operator.
PHP Elvis operator vs null coalescing operator
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'
.
Ternary Operator(Elvis Operator) ?:
This is because you make a boolean check in the first example:
$complete == 'complete' // returns 'true'
And the operator tells, if the statement is true, return the value of the statement, otherwise return 'not Complete'. So it does. And true
is represented as 1
.
Explained by your examples:
// sets '$completed' to '($complete == 'complete')' what is 'true'
$completed = ($complete == 'complete') ?: 'Not Complete';
// sets '$completed' to '$completed', what is 'NULL', because '$completed' seems to be undefined before
$completed = ($complete == 'complete') ? $completed : 'Not Complete';
// sets '$completed' to the value of '$complete', because the statement is 'true'
if ($complete == 'complete') {
$completed = $complete;
} else {
$completed = 'Not Complete';
}
How does null safe operator works in php 8?
What it does is surely explained in the blog post you found it mentioned in.
How it works is best explained by a simple bytecode dump:
L3 #0 JMP_NULL $null J5 @1
L3 #1 FETCH_OBJ_R $null "optional" ~0
L3 #2 JMP_NULL ~0 J5 @1
L3 #3 INIT_METHOD_CALL ~0 "maybenull"
L3 #4 DO_FCALL
L4 #5 RETURN<-1> 1
Any occurence of ?->
is represented by an attribute fetch or method call, but preceded with JMP_NULL
, that would simply skip the remainder of the expression.
How to replace if statement with a ternary operator ( ? : )?
The
(condition) ? /* value to return if condition is true */
: /* value to return if condition is false */ ;
syntax is not a "shorthand if" operator (the ?
is called the conditional operator) because you cannot execute code in the same manner as if you did:
if (condition) {
/* condition is true, do something like echo */
}
else {
/* condition is false, do something else */
}
In your example, you are executing the echo
statement when the $address
is not empty. You can't do this the same way with the conditional operator. What you can do however, is echo
the result of the conditional operator:
echo empty($address['street2']) ? "Street2 is empty!" : $address['street2'];
and this will display "Street is empty!" if it is empty, otherwise it will display the street2 address.
How can I use Nullsafe operator in PHP
PHP 7
$country = null;
if ($session !== null) {
$user = $session->user;
if ($user !== null) {
$address = $user->getAddress();
if ($address !== null) {
$country = $address->country;
}
}
}
PHP 8
$country = $session?->user?->getAddress()?->country;
Instead of null check conditions, you can now use a chain of calls with the new nullsafe operator. When the evaluation of one element in the chain fails, the execution of the entire chain aborts and the entire chain evaluates to null.
source: https://www.php.net/releases/8.0/en.php
Is there a fancy and short solution for using the null coalescing operator with constants in PHP?
true way is detect all undefined constants and define: defined('MY_CONSTANT') || define('MY_CONSTANT', 'baz');
and etc.
if you want save this trash constructions, then you can use something like this get_defined_constants()['MY_CONSTANT'] ?? 'baz'
Is there a shorter syntax for the ternary operator in php?
Yes it's possible in PHP7 with Null coalescing operator (??
)
$variable = $array["property"] ?? DEFAULT_VALUE_CONSTANT;
If you are using PHP version < 7 one solution is use the elvis operator
$variable = $array["property"] ?: DEFAULT_VALUE_CONSTANT;
Please avoid using @
instead of isset()
.
References:
?: operator (the 'Elvis operator') in PHP
if else for PHP ternary operator using datatable
You have to wrap certain parts otherwise the reader does not know what depends on what. Try this:
<td>".(($row['CheckType']=='I') ? 'TIME-IN' : (($row['CheckType']=='O') ? 'TIME-OUT' : (($row['CheckType']=='i') ? 'OVERTIME-IN': (($row['CheckType']=='o') ? 'OVERTIME-OUT' : 'N/A'))))."</td>
PS: actualy it´s not that good to use nested ternary operators, because it´s bad to read.
Related Topics
Is There a PHP Library For Email Address Validation
PHP Script to Loop Through All of the Files in a Directory
Why Is Json_Encode Adding Backslashes
: Operator (The 'Elvis Operator') in PHP
How to Upload & Save Files With Desired Name
Is the Leading Colon For Parameter Names Passed to Pdostatement::Bindparam() Optional
PHP Sessions That Have Already Been Started
Remove Text Between Parentheses PHP
Which One Is the Best Pdf-API For PHP
Sqlstate[Hy000] [2002] Connection Refused Within Laravel Homestead
How to Check What User PHP Is Running As
How to Avoid Echoing Character 65279 in PHP
Which $_Server Variables Are Safe
Redefine Built in PHP Functions
What Is the Canonical Way to Determine Commandline Vs. Http Execution of a PHP Script