PHP null-safe and null-coalescing operators

#php

The null-safe operator supports method while the null-coalescing operator doesn't. The null-coalescing operator supports array while the null-safe operator doesn't.

Null-coalescing Operator (??)

PHP7 came with syntactic flavourings we all have been savouring ever since its release - One of which is the null-coalescing operator. If you have ever had to use the ternary operator together with isset() method, then this was tailor-made for you!

$developer_status = $coding ?? $sleeping;

// is equivalent to
$developer_status = isset($coding) ? $coding : $sleeping;

It returns the first operand if true, otherwise returns the second. It is also chainable:

$developer_status = $coding ?? $sleeping ?? $eating;

Null-safe Operator (?->)

The null-safe is a PHP8 feature that, instead of throwing an exception, short-circuits to null when a chained property or method access is null and the rest of the chain is skipped.

It is an elegant way of wrapping is_null around each property or method access.

Let's examine the following code snippet:

$recentlyActive = null;

if (session()->has('user')) {
    $user = session('user');

    if (! is_null($user)) {
        $lastLoggedIn = $user->lastLoggedIn();

        if (! is_null($lastLoggedIn)) {
            $recentlyActive = $lastLoggedIn->withinLast7Days();
        }
    }
}

With null-safe operator, we can be more efficient by writing less and clearer code:

$recentlyActive = session()->has('user')?->lastLoggedIn?->withinLast7Days();

Versus

What is the difference between null-safe operator and null-coalescing operator. Hint: it's not just in the syntax, it is also in the semantics.

The null-safe operator supports method while the null-coalescing operator doesn't. The null-coalescing operator supports array while the null-safe operator doesn't.

// this works
$array = [];

var_dump($array['mukulli']->kofa ?? null);


// this throws a warning
var_dump($array['mukulli']?->kofa);

// Warning: Undefined array key "key"

Null-safe with methods:

class Order
{
    public function date(): ?Carbon { /* … */ }
    
    // …
}

$order = new Order();

var_dump($order->date()?->format('Y-m-d'));

// null

Did you enjoy this post?

Sign up for my newsletter to stay up to date.

You will receive monthly updates on my latest articles and products. I do care about the protection of your data. Read my Privacy Policy.