Коллеги, кто хоть раз видел «Call to a member function on null», тот уже познал боль. Обычно это происходит так: запрос к MySQL вернул ноль строк, а код всё равно пытается вызвать метод у объекта.
Раньше писали так:
$phone = null;
if ($user !== null && $user->profile !== null) {
$phone = $user->profile->phone;
}Длинно, скучно и легко забыть одну проверку. В продакшене это мгновенно превращается в фатал.
В PHP 8+ есть nullsafe оператор ?->:
$phone = $user?->profile?->phone;Если $user равен null, цепочка не падает, а просто вернёт null. Дальше решаем сами: дефолт, бейдж, 404 или лог.
Где реально выручает:
— $user из репозитория: SELECT ... LIMIT 1 может вернуть пустоту;
— связи: $order?->customer?->email;
— DTO и сущности, где часть полей не заполнена.
Но нюансы из мастерской:
— ?-> хорош там, где «нет данных» — нормальный сценарий.
— Если объект обязан быть, не прячьте ошибку. Лучше исключение или проверка на уровне сервиса.
— Для массивов он не подходит: используем $data['phone'] ?? null.
— Не заменяет типизацию. ?User $user = null и строгие контракты всё ещё спасают.
— Если используете PDO, не путайте false и null. Удобнее, когда репозиторий возвращает ?User, а не сырой результат fetch().
Пример:
$user = $repo->findById($id);
$email = $user?->getContact()?->getEmail();
return $email ?? 'не указан';Меньше лесенки из if, больше читаемости. Но помним: nullsafe — не магия, а аккуратный способ работать с пустыми результатами БД.
Вот так. Идем кодить дальше! 🚀