PHP 8.4 引入了惰性对象,这是一项设计旨在推迟对象初始化的特性,直到该对象被访问为止。这种方法降低了资源使用,尤其是对于那些可能只有在执行期间偶尔被使用的重初始化逻辑的对象。
惰性对象通过动态创建的代理对象来推迟目标对象构造函数的执行。反射是生成该代理的关键,它模拟原始类,允许实际对象在被访问之前保持未初始化状态。
<?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;
如下输出
访问方法会触发初始化
对象已创建
调用对象, 输出 1
在这个例子中,当对象被创建时,MyClass
的构造函数会立即被调用,从而显示“访问方法会触发初始化”。该类有一个在运行时初始化的私有属性 $foo
。
使用惰性对象:
<?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;
如下输出
惰性对象已创建
访问方法会触发初始化
调用惰性对,输出 123
在这段代码中,newLazyGhost
方法创建了一个惰性对象。初始化函数被定义为仅在调用方法时才初始化对象。ReflectionClass
对象负责创建一个非 MyClass
完整实例的代理对象,在调用 getFoo()
之前。
当 getFoo()
被调用时,构造函数被启动(显示“访问方法会触发初始化”),对象被初始化为 123,如输出所示。
延迟实例化减少内存使用,提高性能,尤其是在对象条件性访问时。
开发人员与惰性对象的交互方式与常规对象相同,无需额外的代理处理工作。
在依赖注入容器、ORM 系统或 API 集成等场景中非常有用,可将初始化推迟到需要时。
惰性对象可能会使序列化和反序列化变得困难,因为它们处于延迟状态。
堆栈跟踪可能包括代理层,使调试稍微复杂一些。
PHP 8.4 中的惰性对象是提升现代应用程序性能和资源效率的强大工具。通过推迟初始化直到必要时,它们提供了一种更清晰、更可扩展的管理复杂对象生命周期的方法。
要了解更多有关惰性对象的信息,请访问官方 PHP RFC 页面。