Is there a "nullsafe operator" in PHP?
Asked Answered
F

4

35

Is there any way to write the following statement using some kind of safe navigation operator?

echo $data->getMyObject() != null ? $data->getMyObject()->getName() : '';

So that it looks like this:

echo $data->getMyObject()?->getName();
Floatable answered 10/9, 2012 at 12:28 Comment(0)
T
72

From PHP 8, you are able to use the null safe operator which combined with the null coalescing operator allows you to write code like:

echo $data->getMyObject()?->getName() ?? '';

By using ?-> instead of -> the chain of operators is terminated and the result will be null.

The operators that "look inside an object" are considered part of the chain.

  • Array access ([])
  • Property access (->)
  • Nullsafe property access (?->)
  • Static property access (::)
  • Method call (->)
  • Nullsafe method call (?->)
  • Static method call (::)

e.g. for the code:

$string = $data?->getObject()->getName() . " after";

if $data is null, that code would be equivalent to:

$string = null . " after";

As the string concatenation operator is not part of the 'chain' and so isn't short-circuited.

Theaterintheround answered 2/8, 2020 at 23:45 Comment(0)
L
13

Nullsafe operator allows you to chain the calls avoiding checking whether every part of chain is not null (methods or properties of null variables).

PHP 8.0

$city = $user?->getAddress()?->city

Before PHP 8.0

$city = null;
if($user !== null) {
    $address = $user->getAddress();
    if($address !== null) {
        $city = $address->city;
    }
}

With null coalescing operator (it doesn't work with methods):

$city = null;
if($user !== null) {
    $city = $user->getAddress()->city ?? null;
}

Nullsafe operator suppresses errors:

Warning: Attempt to read property "city" on null in Fatal error:

Uncaught Error: Call to a member function getAddress() on null

However it doesn't work with array keys:

$user['admin']?->getAddress()?->city //Warning: Trying to access array offset on value of type null

$user = [];
$user['admin']?->getAddress()?->city //Warning: Undefined array key "admin"
Lafountain answered 27/11, 2020 at 22:41 Comment(1)
I think it's not optimal that it doesn't work with array keys. It's almost intuitive that it should...Bravery
L
7

No there is not.

The absolute best way to deal with this is to design your objects in a way that they always return a known, good, defined value of a specific type.

For situations where this is absolutely not possible, you'll have to do:

$foo = $data->getMyObject();
if ($foo) {
    echo $foo->getName();
}

or maybe

echo ($foo = $data->getMyObject()) ? $foo->getName() : null;
Laurenlaurena answered 10/9, 2012 at 12:34 Comment(4)
Okay. At least your second suggestion is a bit shorter than mine.Floatable
I think that this would be a good addition to PHP language. After the ?? operator, something like the ?. operator of C#. So something like this could be written: $stringVar = $datetimeobject?->format("Y-m-d")Richthofen
There is an RFC draft for "nullsafe" operator ?-> since December 2014: wiki.php.net/rfc/nullsafe_calls. But it's still a draft.Deettadeeyn
@dec you may want to edit this answer as PHP8 has the feature.Countryandwestern
S
2

For Laravel before PHP 8.0, you can use optional()

$city = optional(optional($user)->getAddress())->city
Shaia answered 15/3, 2023 at 10:5 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.