ReflectionClass::newLazyGhost
(PHP 8 >= 8.4.0)
ReflectionClass::newLazyGhost — 新しいレイジーゴーストインスタンスを作成する
説明
クラスの新しいレイジーゴーストインスタンスを作成し、
initializer
をアタッチします。コンストラクタは呼び出されず、
プロパティはデフォルト値に設定されません。オブジェクトの状態を
初めて参照または変更する時に、
initializer
をにより自動的に初期化されます。
初期化トリガーおよび
初期化シーケンス
を参照してください。
パラメータ
initializer
-
イニシャライザは以下のシグネチャを持つコールバックです:
object
-
初期化される
object
。この時点では、 オブジェクトはもはやレイジーとしてマークされておらず、 アクセスしても再び初期化がトリガーされることはありません。
initializer
関数はnull
を返すか、 値を返さない必要があります。 options
-
options
には以下のフラグを組み合わせて 指定できます:-
ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE
- デフォルトでは、レイジーオブジェクトのシリアライズは 初期化がトリガーされます。このフラグを設定すると、 初期化せずにシリアライズできるようになります。
-
戻り値
レイジーゴーストインスタンスを返します。オブジェクトにプロパティがない場合、または そのプロパティがすべてstaticまたはvirtualの場合、通常の(レイジーではない)インスタンスが 返されます。 レイジーオブジェクトの ライフサイクルも参照してください。
例
例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)
参考
- レイジーオブジェクト
- ReflectionClass::newLazyProxy() - 新しいレイジープロキシインスタンスを作成する
- ReflectionClass::newInstanceWithoutConstructor() - コンストラクタを起動せずに新しいクラスのインスタンスを作成する
- ReflectionClass::resetAsLazyGhost() - オブジェクトをリセットしてレイジーとしてマークする
- ReflectionClass::markLazyObjectAsInitialized() - イニシャライザまたはファクトリを呼び出さずレイジーオブジェクトを初期化済みとしてマークする
- ReflectionClass::initializeLazyObject() - レイジーオブジェクトを強制的に初期化する
- ReflectionClass::isUninitializedLazyObject() - オブジェクトがレイジーで未初期化かどうかを調べる
- ReflectionProperty::setRawValueWithoutLazyInitialization() - 遅延初期化をトリガーせず生のプロパティ値を設定する
- ReflectionProperty::skipLazyInitialization() - プロパティを非レイジーとしてマークする
- ReflectionProperty::isLazy() - プロパティがレイジーであるかどうかを調べる
+add a note
User Contributed Notes 1 note
dave1010 at gmail dot com ¶
27 days ago
Simple helper function that makes it easier to understand:
<?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) {
// Initialize via the main initializer if provided
if ($initializer) {
$initializer($object);
}
// Set properties using the callables if provided
if ($propertySetterCallables) {
foreach ($propertySetterCallables as $property => $callable) {
if (is_callable($callable)) {
$object->$property = $callable();
}
}
}
});
}
?>
This supports using either a main object initializer and/or property initializers.
Here's an example, where generating order IDs and calculating totals is considered expensive, so we only do it when necessary:
<?php
class Order {
public string $orderId = '';
public float $total = 0.0;
}
$initializer = function (Order $order) {
$order->orderId = 'ORD12345';
};
$propertySetters = [
'total' => fn() => 200.75,
];
// Lazy ghost with both an initializer and property callables
$lazyOrder = createLazyGhost(Order::class, $initializer, $propertySetters);
// We can now use $lazyOrder as normal, even though the properties haven't been calculated yet.
// Do something that triggers initialization
echo $lazyOrder->orderId . PHP_EOL;
echo $lazyOrder->total . PHP_EOL;
?>