PHP Conference Japan 2024

ReflectionClass::newLazyGhost

(PHP 8 >= 8.4.0)

ReflectionClass::newLazyGhost创建一个新的延迟幽灵实例

描述

public ReflectionClass::newLazyGhost(callable $initializer, int $options = 0): object

创建一个类的新的延迟幽灵实例,并将 initializer 附加到它。构造函数不会被调用,属性也不会被设置为其默认值。但是,当第一次观察或修改其状态时,对象将通过调用 initializer 自动初始化。请参阅 初始化触发器初始化序列

参数

initializer
初始化器是一个具有以下签名的回调函数

initializer(object $object): void
object
正在初始化的 object。此时,对象不再被标记为延迟,访问它不会再次触发初始化。

initializer 函数必须返回 null 或不返回值。
options

options 可以是以下标志的组合

ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE
默认情况下,序列化延迟对象会触发其初始化。设置此标志可以防止初始化,允许序列化延迟对象而无需初始化。

返回值

返回一个延迟幽灵实例。如果对象没有属性,或者如果其所有属性都是静态或虚拟的,则返回一个正常的(非延迟)实例。另请参阅 延迟对象的生命周期

错误/异常

如果类是内部类或扩展了内部类(除了 stdClass),则会抛出一个 Error

示例

示例 #1 基本用法

<?php

class Example {
public function
__construct(public int $prop) {
echo
__METHOD__, "\n";
}
}

$reflector = new ReflectionClass(Example::class);
$object = $reflector->newLazyGhost(function (Example $object) {
$object->__construct(1);
});

var_dump($object);
var_dump($object instanceof Example);

// 触发初始化,并在之后获取属性
var_dump($object->prop);

?>

以上示例将输出

lazy ghost object(Example)#3 (0) {
  ["prop"]=>
  uninitialized(int)
}
bool(true)
Example::__construct
int(1)

参见

添加注释

用户贡献的笔记 1 条笔记

1
dave1010 at gmail dot com
9 天前
一个简单的辅助函数,使理解更容易

<?php

function createLazyGhost(
string $class,
?callable
$initializer = null,
?array
$propertySetterCallables = null
): object {
$reflection = new ReflectionClass($class);

return
$reflection->newLazyGhost(function (object $object) use ($initializer, $propertySetterCallables) {
// 如果提供了,则通过主初始化器进行初始化
if ($initializer) {
$initializer($object);
}

// 如果提供了,则使用回调函数设置属性
if ($propertySetterCallables) {
foreach (
$propertySetterCallables as $property => $callable) {
if (
is_callable($callable)) {
$object->$property = $callable();
}
}
}
});
}

?>

这支持使用主对象初始化器和/或属性初始化器。

这是一个示例,其中生成订单 ID 和计算总计被认为是昂贵的操作,因此我们只在必要时才执行。

<?php

class Order {
public
string $orderId = '';
public
float $total = 0.0;
}

$initializer = function (Order $order) {
$order->orderId = 'ORD12345';
};

$propertySetters = [
'total' => fn() => 200.75,
];

// 使用初始化器和属性回调的延迟幽灵对象
$lazyOrder = createLazyGhost(Order::class, $initializer, $propertySetters);

// 现在我们可以像平常一样使用 $lazyOrder,即使属性还没有被计算。

// 执行触发初始化的操作
echo $lazyOrder->orderId . PHP_EOL;
echo
$lazyOrder->total . PHP_EOL;

?>
To Top