PHP 中的 null 安全操作与 ?-> 操作符
什么是 ?-> 操作符
?-> 是 PHP 8.0 引入的 null 安全操作符 (Null Safe Operator),用于安全地访问可能为 null 的对象属性或方法。

基本语法
// 传统写法
if ($user !== null) {
$name = $user->getName();
} else {
$name = null;
}
// 使用 ?-> 操作符
$name = $user?->getName();
实际应用示例
1 方法链调用
// 传统写法
$country = null;
if ($user !== null) {
$address = $user->getAddress();
if ($address !== null) {
$country = $address->getCountry();
}
}
// 使用 ?-> 操作符
$country = $user?->getAddress()?->getCountry();
2 属性访问
class User {
public ?string $name = null;
public ?Address $address = null;
}
$user = new User();
// 安全访问属性
$city = $user?->address?->city;
// 等价于:$user 或 $address 为 null,返回 null
3 数组访问
// ?-> 不适用于数组,需要使用 ?? (null 合并操作符) $data = ['user' => ['name' => 'John']]; $name = $data['user']?['name'] ?? null; // 错误 $name = $data['user']['name'] ?? null; // 正确
与传统写法的对比
class Order {
public ?Customer $customer = null;
}
class Customer {
public ?Address $address = null;
public function getEmail(): ?string {
return $this->email;
}
}
// 传统空检查
$email = null;
if ($order !== null && $order->customer !== null) {
$email = $order->customer->getEmail();
}
// 使用 ?-> 操作符
$email = $order?->customer?->getEmail();
// 结合 null 合并操作符
$email = $order?->customer?->getEmail() ?? 'default@email.com';
重要注意事项
1 返回类型
// ?-> 总是返回 null 或实际值 $result = $obj?->method(); // 返回 mixed|null // 不适用于函数返回值 $result = getObject()?->method(); // 正确 $result = (getObject())?->method(); // 正确
2 链式调用限制
class User {
public function getProfile(): ?Profile { ... }
}
class Profile {
public function getName(): string { ... }
}
// 可以链式调用
$name = $user?->getProfile()?->getName();
// 但不能在 ?-> 后直接调用非空方法
// $name = $user?->getProfile()->getName(); // getProfile() 返回 null,报错
3 与 null 合并操作符的区别
// ?-> 用于方法/属性访问 $value = $object?->property; // ?? 用于提供默认值 $value = $object->property ?? 'default'; // 组合使用 $value = $object?->property ?? 'default'; // $object 为 null,返回 'default' // $object->property 为 null,返回 'default'
实际项目示例
// 用户信息获取
class UserService {
public function getUserDisplayName(?User $user): string {
// 安全获取用户显示名
return $user?->profile?->displayName
?? $user?->username
?? 'Anonymous';
}
public function getUserAddress(?User $user): ?string {
// 获取地址信息
return $user?->address?->getFullAddress();
}
}
// 复杂对象查询
class OrderProcessor {
public function getOrderShippingInfo(Order $order): ?string {
return $order
?->shipping
?->address
?->getFullAddress();
}
}
最佳实践
- 优先使用
?->替代多层 if 检查 - 配合 提供默认值
- 不要过度使用 - 只在可能为 null 的地方使用
- 注意性能影响 - 每个
?->都有轻微开销
兼容性要求
- PHP 8.0 及以上版本
- 不能用于数组访问(使用 )
- 不能用于可写上下文
?-> 操作符大大简化了 PHP 中 null 安全检查的代码,使代码更加简洁、可读性更强,同时减少了因空值导致的错误。