← Back to blog

PHP ternary operator, elvis operator, null coalescing operator, and null safe operator

| PHP

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 inline if-else that 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.
Share