PHP ternary operator, elvis operator, null coalescing operator, and null safe operator
This article was published over 2 years ago. Some information may be outdated.
Ternary Operator
Ternary Operator (?:) is an inline if-else statement.
Consider the following example:
$status = true;
$statusText = null;
if ($status === true) {
$statusText = 'OK';
} else {
$statusText = 'Fail';
}
Using the ternary operator, you can eliminate the entire if-else statement and replace it with a concise syntax:
$status = true;
$statusText = $status === true ? 'OK' : 'Fail';
Elvis Operator
Elvis operator (?:) returns its first operand if that operand evaluates to a true value.
Here is how it works:
$statusText = 'OK';
if ($statusText === "OK") {
echo "OK";
} else {
echo "Fail";
}
The value of $statusText is repeated twice. Instead, use the Elvis operator:
$statusText = 'OK';
echo $statusText ?: "Fail";
The variable must be defined before using the Elvis operator. The following code throws an error:
echo $statusText ?: "Fail";
PHP Notice: Undefined variable: statusText in operators.php on line 2
The fix:
if (isset($statusCode)) {
echo $statusText ?: "Fail";
}
Null coalescing operator
This operator was introduced in PHP 7.0.
Null coalescing operator (??) works the same way as the Elvis operator, except it does not trigger a notice if the variable is undefined or has a null value -- hence the name null coalescing:
echo $statusText ?? "Fail";
Empty values, false and 0 are considered NOT null, so they will be returned:
var_dump('' ?? "Second Value"); // string(0) ""
var_dump(false ?? "Second Value"); // bool(false)
var_dump(0 ?? "Second Value"); // int(0)
Using it on an undefined class property:
class Person { }
$person = new Person();
echo $person->name ?? 'No name'; // No name
That works, but what about nested class properties?
Look at this example:
interface Country { }
class Iraq implements Country
{
public string $name = 'Iraq';
}
class Person
{
public ?Country $country = null;
public function __construct(?Country $country) {
$this->country = $country;
}
}
$person = new Person(nulll);
echo 'I am are from: ' . $person->country->name;
PHP Warning: Attempt to read property "name" on null in ...
The country property on the Person class accepts either a Country interface or a null value, but the code always expects it to have a Country object.
Here is how to fix it in PHP < 8.0:
if ($country = $person->country) {
echo 'I am from '. $country->name;
}
Null safe operator
This operator was introduced in PHP 8.0.
The null safe operator (?->) does not throw an exception if you try to access the name property on null:
echo $person->country?->name;
It tells PHP to get the name property if the object exists, otherwise ignore it.
Summary
- Ternary operator (
?:) -- an inlineif-elsethat condenses conditional assignment into a single expression. - Elvis operator (
?:) -- returns the first operand if truthy, but the variable must be defined beforehand to avoid a notice. - Null coalescing operator (
??) -- works like the Elvis operator but does not trigger a notice for undefined or null variables; introduced in PHP 7.0. - Null safe operator (
?->) -- safely accesses properties or methods on a potentially null object without throwing an exception; introduced in PHP 8.0.