PHP Conference Japan 2024

ReflectionClass::newLazyGhost

(PHP 8 >= 8.4.0)

ReflectionClass::newLazyGhost建立新的惰性幽靈實例 (Lazy Ghost Instance)

說明

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
預設情況下,序列化延遲載入物件會觸發其初始化。設定此旗標可防止初始化,允許延遲載入物件在不被初始化的情況下序列化。

回傳值

回傳一個延遲載入的幽靈物件 (ghost instance)。如果物件沒有屬性,或者它的所有屬性都是靜態或虛擬的,則會回傳一個普通的(非延遲載入)物件實例。另請參閱 延遲載入物件的生命週期

錯誤/例外

如果該類別是內建類別或繼承自內建類別(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 則註釋

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

類別 訂單 {
public
string $訂單編號 = '';
public
float $總金額 = 0.0;
}

$初始化器 = function (訂單 $訂單) {
$訂單->訂單編號 = 'ORD12345';
};

$屬性設定器 = [
'總金額' => fn() => 200.75,
];

// 延遲載入物件,同時具備初始化器和屬性可呼叫函式
$延遲載入訂單 = 建立延遲載入物件(訂單::class, $初始化器, $屬性設定器);

// 現在我們可以正常使用 $延遲載入訂單,即使屬性尚未計算。

// 執行一些會觸發初始化的動作
echo $延遲載入訂單->訂單編號 . PHP_EOL;
echo
$延遲載入訂單->總金額 . PHP_EOL;

?>
To Top