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 合并,提供默认值。

相关推荐
不正经的小寒44 分钟前
PHP 8.2 核心特性
php
不正经的小寒1 小时前
PHP 8.1 核心特性
php
SEO_juper4 小时前
CDN 地域节点优化:匹配 GEO 信号,提升加载速度
服务器·ai·php·seo·cdn·geo·谷歌优化
dog2505 小时前
解析几何的现代范式-算力,拟合与对偶
服务器·开发语言·网络·线性代数·php
淘矿人5 小时前
【AI大模型】AI 大模型推理平台完整测评:8 家主流聚合服务对比分析
人工智能·sql·gpt·学习·github·php
XiYang-DING8 小时前
【Java EE】TCP—滑动窗口
tcp/ip·java-ee·php
.千余9 小时前
【Linux】网络基础2---Socket编程预备
linux·网络·php
雪度娃娃10 小时前
Asio异步读写——简单服务器和客户端异步通信
运维·服务器·网络·c++·php
中科三方10 小时前
域名解析修改后,用户仍访问旧IP?原因排查与高效解决指南
网络协议·tcp/ip·php
码农老李1 天前
openEuler2403服务器版 原生官方镜像和飞腾定制镜像
开发语言·php