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

相关推荐
BingoGo2 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php
JaguarJack2 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php·服务端
BingoGo3 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php
JaguarJack3 天前
OpenSwoole 26.2.0 发布:支持 PHP 8.5、io_uring 后端及协程调试改进
后端·php·服务端
JaguarJack4 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
后端·php·服务端
BingoGo4 天前
推荐 PHP 属性(Attributes) 简洁读取 API 扩展包
php
JaguarJack5 天前
告别 Laravel 缓慢的 Blade!Livewire Blaze 来了,为你的 Laravel 性能提速
后端·php·laravel
郑州光合科技余经理5 天前
代码展示:PHP搭建海外版外卖系统源码解析
java·开发语言·前端·后端·系统架构·uni-app·php
QQ5110082855 天前
python+springboot+django/flask的校园资料分享系统
spring boot·python·django·flask·node.js·php
WeiXin_DZbishe5 天前
基于django在线音乐数据采集的设计与实现-计算机毕设 附源码 22647
javascript·spring boot·mysql·django·node.js·php·html5