php8 ?-> nullsafe 操作符 使用教程

简介

PHP 8 引入了 ?->Nullsafe 操作符),用于简化 null 检查,减少繁琐的 if 语句或 isset() 代码,提高可读性。

?-> Nullsafe 操作符的作用

PHP 7 及以下,访问对象的属性或方法时,如果对象是 null,会导致致命错误 (Fatal error):

php 复制代码
$person = null;
echo $person->name; // Fatal error: Uncaught Error: Trying to get property of non-object

解决方案(传统写法):

php 复制代码
$person = null;
echo isset($person) ? $person->name : null;

PHP 8 解决方案(?->):

php 复制代码
$person = null;
echo $person?->name; // 不会报错,直接返回 null

?-> 基本用法

访问对象的属性

php 复制代码
class Person {
    public string $name = "John";
}

$person = new Person();
echo $person?->name; // 输出 "John"

$person = null;
echo $person?->name; // 输出 null,不会报错

访问对象的方法

php 复制代码
class User {
    public function getName() {
        return "Alice";
    }
}

$user = new User();
echo $user?->getName(); // 输出 "Alice"

$user = null;
echo $user?->getName(); // 输出 null,不会报错

访问嵌套对象

php 复制代码
class Address {
    public string $city = "New York";
}

class Person {
    public ?Address $address = null;
}

$person = new Person();
echo $person->address?->city; // 输出 null,不会报错

$person->address = new Address();
echo $person->address?->city; // 输出 "New York"

?-> 结合数组

不能用于数组索引([]),但可以用于 ArrayAccess 对象

php 复制代码
$data = null;
echo $data?['key']; // 语法错误:不能用于数组

解决方案:使用 ArrayAccess 对象

php 复制代码
class Collection implements ArrayAccess {
    private array $items = ['name' => 'Alice'];

    public function offsetExists($offset) { return isset($this->items[$offset]); }
    public function offsetGet($offset) { return $this->items[$offset] ?? null; }
    public function offsetSet($offset, $value) { $this->items[$offset] = $value; }
    public function offsetUnset($offset) { unset($this->items[$offset]); }
}

$collection = new Collection();
echo $collection?->offsetGet('name'); // 输出 "Alice"

$collection = null;
echo $collection?->offsetGet('name'); // 输出 null,不会报错

?-> 结合函数返回值

php 复制代码
function getUser() {
    return null;
}

echo getUser()?->name; // 输出 null,不会报错

?-> 结合链式调用

PHP 8 允许链式 ?-> 操作,简化复杂的 null 检查:

php 复制代码
class Department {
    public ?Person $manager = null;
}

$department = new Department();

// 传统写法
echo isset($department->manager) ? $department->manager->name : null;

// PHP 8 `?->`
echo $department?->manager?->name; // 输出 null,不会报错

?-> 结合赋值

?-> 不能用于赋值,只能用于访问!

php 复制代码
$person = null;

// 不能用 `?->` 进行赋值
$person?->name = "John"; // 语法错误

解决方案:

php 复制代码
if ($person !== null) {
    $person->name = "John";
}

?-> 不能用于静态方法

php 复制代码
class Test {
    public static function hello() {
        return "Hello";
    }
}

echo Test?->hello(); // ❌ 语法错误

静态方法必须用 :: 访问,不支持 ?->

解决方案:

php 复制代码
echo isset(Test::hello) ? Test::hello() : null;

?-> 和 ?? 的区别

?-> 用于对象,?? 用于 null 合并

php 复制代码
$person = null;

// `?->` 适用于对象
echo $person?->name; // 返回 null

// `??` 适用于变量为空时提供默认值
echo $person?->name ?? "Default Name"; // 输出 "Default Name"
  • ?-> 用于安全访问对象的属性或方法。

  • ?? 用于 null 合并,提供默认值。

相关推荐
m0_380743873 小时前
给 Claude API 调用补上超时重试和错误分类
开发语言·人工智能·php
yuewell_ai5 小时前
机器人调度通讯怎么设计才不会被网络抖动瘫痪
网络·机器人·php
FfHUCisI15 小时前
GMP 调度器:Go 并发的心脏是如何跳动的
开发语言·golang·php
星云API技术支持16 小时前
企业微信二次开发外部群:群聊数据与联系人信息如何建立关联
数据库·php·企业微信
sbjdhjd1 天前
PHP eval 型 RCE:flag 正则过滤与通配符绕过实操 | 01
安全·web安全·网络安全·开源·系统安全·php·网络攻击模型
qetfw2 天前
Debian Nginx + PHP-FPM 配置:FastCGI、站点目录与访问验证
linux·nginx·debian·php
啊阿狸不会拉杆2 天前
《计算机网络-自顶向下方法》3.6 拥塞控制原理 读书笔记
计算机网络·智能路由器·php
郑州光合科技余经理2 天前
本地生活服务系统:成品模块和定制接口怎么划界
java·前端·人工智能·后端·系统架构·php·ai编程
LorryJovens2 天前
【LAAP科研】CEN因果等价网络理论---从双缝干涉到因果等价
开发语言·php
Casual2 天前
【网络基础进阶】:看懂子网划分与 VLAN
开发语言·网络·php