PHP 8.0: Оператор Null-safe
Содержание

Безопасный вызов методов
Представленный в PHP 8 оператор nullsafe (?->
)позволяет вам вызывать методы объекта или получать доступ к свойствам объекта в цепочке связанных объектов, где объект в цепочке потенциально может быть null
. Его синтаксис аналогичен оператору доступа к свойству/методу (->
).
$foo?->bar?->baz;
Оператор null safe по умолчанию возвращает null
, если выражение в левой части оценивается как null
.
class Customer { public function getAddress(): ?Address {} } class Address { public function getCountry(): string {} } $country = $customer->getAddress()->getCountry();
В приведенном выше фрагменте возвращаемое значение метода Customer::getAddress()
является nullable и он может вернуть null
или объект класса Address
.
Цепочка $customer->getAddress()->getCountry()
не является "null safe", поскольку возвращаемое значение getAddress
может быть равно null
и PHP выдает ошибку при попытке вызвать метод getCountry()
:
Fatal error: Uncaught Error: Call to a member function getCountry() on null in ...:...
Для безопасного доступа к адресу необходимо проверить на null
возвращаемое значение перед дальнейшим обращением к возвращаемому значению.
$address = $customer->getAddress(); $country = $address ? $address->getCountry() : null;
$address = $customer->getAddress(); if ($address) { $country = $address->getCountry(); } else { $country = null; }
Оператор null-safe решает эту проблему, замыкая доступ к свойству\методу и немедленно возвращает null
, если левая часть оператора равна null
, не выполняя остальную часть выражения.
// $address = $customer->getAddress(); // $country = $address ? $address->getCountry() : null; $country = $customer->getAddress()?->getCountry();
Оператор ?->
null-safe может помочь сократить излишние проверки isset() и использование тернарного оператора.
Read-Only (Только для чтения)
Оператор null-safe предназначен только для чтения. Из него нельзя записывать/присваивать значения.
class Customer { private ?Address $address; public function getAddress(): ?Address { return $this->address; } } class Address { public string $country; } $customer->getAddress()?->country = 'NL';
Этот фрагмент пытается записать в свойство $country
объекта Address
. Это недопустимо при использовании оператора null-safe.
atal error: Can't use nullsafe operator in write context in ... on line ...
Chaining (Цепочки)
Оператор null-safe может быть соединен в цепочку, и выражение в целом будет замыкаться с первым оператором null-safe, встретившим null.
$customer->getAddress()?->getCoordinates()->getLongitude()->format();
Эта цепочка вызовов является null-безопасной. PHP остановится и немедленно вернет null
, если любой из null-safe операторов вернет null
.
Оператор Null-safe должен присутствовать на каждом шаге, на котором цепочка может быть замкнута. Использование оператора ?->
не сделает всю цепочку null-safe.
Evaluated from left to right (Оценивание слева направо)
Оператор null-safe выполняется слева направо. Самое главное, что он не определяет приоритет других вызовов функций или других моделей доступа, таких как доступ к массиву.
class Customer { public function getAddress(): ?Address {} } class Address { public function setCountry(string $country_code): void {} } $customer->getAddress()?->setCountry(GeoIP::getCountry());
Если метод Customer::getAddress
возвращает валидный объект Address
, будет выполнен метод GeoIP::getCountry()
, который будет передан в вызов метода Address::setCountry()
. Поскольку операторы null-safe оцениваются слева направо, метод GetIP::getCountry()
никогда не будет вызван, если метод Customer::getAddress()
вернет null
.
$customer->getAddress()?->setCountry((GeoIP::getAddress()?->getCountry()))
Если Customer::getAddress()
возвращает значение, отличное от null
, будет выполнена цепочка (GeoIP::getAddress()?->getCountry())
, и возвращаемое значение будет передано в вызов Address::setCountry()
.
No References (Ссылки отсутствуют)
Оператор null-safe не может быть использован со ссылками.
$country = &$customer->getAddress()?->getCountry();
Fatal error: Cannot take reference of a nullsafe chain in ... on line ...
Backwards Compatibility Impact (Обратная совместимость)
Оператор Null-safe - это новый синтаксис, который не может быть перенесен в старые версии PHP. Запуск кода, использующего оператор null-safe, приведет к ошибке:
Parse error: syntax error, unexpected '->' (T_OBJECT_OPERATOR) in ... on line ...