PHP 8.4 新特性 惰性对象

PHP 8.4 引入了惰性对象,这是一项设计旨在推迟对象初始化的特性,直到该对象被访问为止。这种方法降低了资源使用,尤其是对于那些可能只有在执行期间偶尔被使用的重初始化逻辑的对象。

默认对象和惰性对象之间有什么区别?

惰性对象通过动态创建的代理对象来推迟目标对象构造函数的执行。反射是生成该代理的关键,它模拟原始类,允许实际对象在被访问之前保持未初始化状态。

php
<?php

class MyClass
{
    public function __construct(private int $foo)
    {
        echo '访问方法会触发初始化'.PHP_EOL;
    }

    public function getFoo(): int
    {
        return $this->foo;
    }
}

$object = new MyClass(1);

echo '对象已创建'.PHP_EOL;
echo '调用对象 '. $object->getFoo(). PHP_EOL;

如下输出

shell
访问方法会触发初始化
对象已创建
调用对象, 输出 1

在这个例子中,当对象被创建时,MyClass 的构造函数会立即被调用,从而显示“访问方法会触发初始化”。该类有一个在运行时初始化的私有属性 $foo

使用惰性对象:

php
<?php

class MyClass
{
    public function __construct(private int $foo)
    {
        echo '访问方法会触发初始化'.PHP_EOL;
    }

    public function getFoo(): int
    {
        return $this->foo;
    }
}

$initializer = static function (MyClass $ghost): void {
    $ghost->__construct(123);
};

$reflector = new ReflectionClass(MyClass::class);
$object = $reflector->newLazyGhost($initializer);

echo '惰性对象已创建'.PHP_EOL;
echo '调用惰性对象 '. $object->getFoo(). PHP_EOL;

如下输出

shell
惰性对象已创建
访问方法会触发初始化
调用惰性对,输出 123

在这段代码中,newLazyGhost 方法创建了一个惰性对象。初始化函数被定义为仅在调用方法时才初始化对象。ReflectionClass 对象负责创建一个非 MyClass 完整实例的代理对象,在调用 getFoo() 之前。

getFoo() 被调用时,构造函数被启动(显示“访问方法会触发初始化”),对象被初始化为 123,如输出所示。

惰性对象的优点:

性能提升:

延迟实例化减少内存使用,提高性能,尤其是在对象条件性访问时。

透明代理:

开发人员与惰性对象的交互方式与常规对象相同,无需额外的代理处理工作。

优化资源管理:

在依赖注入容器、ORM 系统或 API 集成等场景中非常有用,可将初始化推迟到需要时。

惰性对象的限制

序列化:

惰性对象可能会使序列化和反序列化变得困难,因为它们处于延迟状态。

调试复杂性:

堆栈跟踪可能包括代理层,使调试稍微复杂一些。

结论

PHP 8.4 中的惰性对象是提升现代应用程序性能和资源效率的强大工具。通过推迟初始化直到必要时,它们提供了一种更清晰、更可扩展的管理复杂对象生命周期的方法。

要了解更多有关惰性对象的信息,请访问官方 PHP RFC 页面。

原文转载

JaguarJack
后端开发工程师,前端入门选手,略知相关服务器知识,偏爱❤️ Laravel & Vue
本作品采用《CC 协议》,转载必须注明作者和本文链接