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();
Nullsafe operator allows you to chain the calls avoiding checking whether every part of chain is not null (methods or properties of null variables).
$city = $user?->getAddress()?->city
$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"
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;
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:
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.
e.g. for the code:
if $data is null, that code would be equivalent to:
As the string concatenation operator is not part of the 'chain' and so isn't short-circuited.