PHP 8 新增了 Nullsafe 操作符(空安全):?->,顾名思义,以一种安全的方式操作可能为 null 的对象。以此可以简化对于 null 值的逻辑判断。
准备
我们先准备一些类和实例。如下:
class FanInfo {
public $total;
}
class User {
public $fanInfo;
}
$user1 = null;
$fanInfo2 = new FanInfo();
$fanInfo2->total = 99;
$user2 = new User();
$user2->fanInfo = $fanInfo2;
以往实现
不严谨的程序员,想获取 user1 的 total 信息时,可能会直接取值。如下:
printf("total: %s\n", $user1->fanInfo->total);
当然,程序会直接报错:
Warning: Attempt to read property "fanInfo" on null
有点经验的程序员这么做(实际会经常这么做):
if ($user1 != null) {
printf("total: %s\n", $user1->fanInfo->total);
}
当然,实际中还需要对 fanInfo 等做一系列判断,也可能无法避免一些嵌套的判断。
Nullsafe 实现
现在有了 Nullsafe 操作符,我们可以直接这样用:
$total1 = $user1?->fanInfo?->total;
printf("type of total1: [%s]\n", gettype($total1));
printf("total1: [%s]\n", $total1);
$total2 = $user2?->fanInfo?->total;
printf("total2: [%s]\n", $total2);
输出结果:
type of total1: [NULL]
total1: []
total2: [99]
当然 user1 为 null 时,表达式直接返回了 null,且不再会调用属性 fanInfo 和后续操作。下面详细介绍求值策略。
短路求值策略
Nullsafe 操作符遵循的是完全短路(Full Short Circuiting)的求值策略。
举例说明:
$foo = $a?->b();
当 a 为 null 时,方法 b 不会被调用,$foo 被赋值为 null。
$a?->b($c->d());
当 a 为 null 时,方法 b 不会被调用,“$c->d()”不会被调用。
$a->b($c?->d());
当 c 为 null 时,方法 d 不会被调用,“$c?->d()”返回值为 null;a 的方法 b 被正常调用。
参考资料
(全文完)