?-> (PHP 8.0) звертається до методу чи властивості, лише якщо об'єкт ліворуч не null. Якщо він null, весь ланцюжок повертає null і далі не виконується (short-circuit).
// До PHP 8
$country = null;
if ($session !== null) {
$user = $session->user();
if ($user !== null && $user->address !== null) {
$country = $user->address->country;
}
}
// PHP 8
$country = $session?->user()?->address?->country;
Short-circuit важливий: якщо $session - null, метод user() навіть не викликається, а аргументи далі по ланцюжку не обчислюються.
Обмеження:
- Лише читання.
$user?->name = 'Оля'- помилка компіляції: присвоювати через?->не можна. - Не працює з масивами:
$data?['key']такого синтаксису немає. Для масивів -??. - Не для посилань:
foo($obj?->prop)у параметр за посиланням не передати. null- не «помилка». Якщо об'єкт мав бути там завжди,?->ховає баг: замість зрозумілого винятку код тихо працює зnull.
Разом з ?? дає значення за замовчуванням:
$city = $order->customer?->address?->city ?? 'Не вказано';
Порада: ?-> - для справді необов'язкових зв'язків (у користувача може не бути профілю). Довгі ланцюжки ?-> - запах: код занадто багато знає про внутрішню будову інших об'єктів, і варто подумати про метод на кшталт $order->shippingCity().