The nullsafe operator, and where it hides a bug

A chain of null checks reads badly and the operator that replaces them is genuinely better — and it makes one specific mistake easier to write.

// the chain it replaces
$city = null;
if ($order !== null && $order->address() !== null) {
    $city = $order->address()->city();
}

$city = $order?->address()?->city();

// and the mistake: this short-circuits the WHOLE chain
$total = $order?->lines()->sum();     // null, silently, if $order is null
// rather than an error saying lines() was called on null

Short-circuiting the entire expression rather than just the next access is correct and is what people do not expect — everything after the first null is skipped, including method calls that would otherwise have thrown. That turns a loud failure into a silent null propagating upward. It also cannot be used as a write target or with [] access, which are the two places people first try it.