Reading a property of null is an error. When you have a chain like $order->customer->address->city, any link might be null, and the whole line can crash.
The nullsafe operator ?-> fixes that. If the value before it is null, PHP stops the chain and returns null.
<?php
class Address
{
public function __construct(public string $city) {}
}
class User
{
public function __construct(public ?Address $address = null) {}
}
$withAddress = new User(new Address("Lucknow"));
$withoutAddress = new User();
echo $withAddress->address?->city . "\n";
var_dump($withoutAddress->address?->city);
Lucknow
NULL
The second call would have caused an error with a plain ->. With ?->, it quietly returns null.
Without it
Before PHP 8.0 you had to write checks by hand.
<?php
class Address { public string $city = "Lucknow"; }
class User { public ?Address $address = null; }
$user = new User();
// Old style
$city = null;
if ($user !== null && $user->address !== null) {
$city = $user->address->city;
}
// With the nullsafe operator
$city2 = $user?->address?->city;
var_dump($city, $city2);
NULL
NULL
Method calls too
It works with methods. The whole rest of the chain is skipped.
<?php
class Profile
{
public function displayName(): string
{
return "Ada";
}
}
$profile = null;
var_dump($profile?->displayName());
NULL
Combine it with ??
Use ?? to supply a default for the null result.
<?php
$profile = null;
echo $profile?->displayName() ?? "Anonymous";
Anonymous
What it does not do
- It does not create missing array keys. For arrays, use
??. - It does not hide every error. If a value is
nulland you needed it, you now get a quietnullinstead of a loud error. Use it wherenullis a normal, expected case.