The Nullsafe Operator ?->

Call a method or read a property on something that might be null, and get null back instead of a fatal error.

Before PHP 8 you wrote defensive pyramids to walk a chain of maybe-null objects. The nullsafe operator ?-> collapses all of that: if the left side is null, the whole expression short-circuits to null and the rest of the chain is skipped.

Easy example

<?php
$country = $session?->getUser()?->getAddress()?->country;
// if $session is null (or any link is null), $country is null
// no 'method call on null' error, no isset() ladder
var_dump($country);

It works for both method calls and property fetches. One caveat: it makes a read safe, but you can't assign through it — $a?->b = 1 is a parse error, which keeps intentions clear.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Safely call getAddress()->getCity() on a user that may not have an address without nested null checks.
  • Chain repository method calls in a single expression that returns null if any step produces null.
  • Read a nested config object property with ?-> and fall back to a default using ?? at the end of the chain.

More examples

Basic nullsafe chain

?-> returns null when the left side is null instead of throwing a fatal error, making optional chains safe.

Example · php
<?php
class Address {
    public function __construct(public string $city) {}
}
class User {
    public ?Address $address = null;
}

$user = new User();

// Without nullsafe: fatal error
// $city = $user->address->city;

$city = $user?->address?->city ?? 'Unknown';
echo $city; // Unknown

Nullsafe method calls

If getInvoice() returns null, getPdf() is never called; the whole chain short-circuits to null.

Example · php
<?php
class Order {
    public function getInvoice(): ?Invoice { return null; }
}
class Invoice {
    public function getPdf(): string { return 'invoice.pdf'; }
}

$order  = new Order();
$pdf    = $order->getInvoice()?->getPdf() ?? 'No invoice';
echo $pdf; // No invoice

Combining with ?? and ->

?-> combined with ?? provides a complete pattern: try the chain, fall back to a default if anything is null.

Example · php
<?php
function getUser(?int $id): ?object {
    if ($id === null) return null;
    return (object)['name' => 'Alice', 'role' => 'admin'];
}

$role = getUser(null)?->role ?? 'guest';
echo $role; // guest

$role = getUser(1)?->role ?? 'guest';
echo $role; // admin

Discussion

  • Be the first to comment on this lesson.