: Operator (The 'Elvis Operator') in PHP

?: 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.

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



Leave a reply



Submit