diff --git a/language/oop5/changelog.xml b/language/oop5/changelog.xml index 7f6e10adfd..aedfec3789 100644 --- a/language/oop5/changelog.xml +++ b/language/oop5/changelog.xml @@ -1,6 +1,6 @@ - + @@ -19,6 +19,12 @@ + + 8.4.0 + + レイジーオブジェクトがサポートされました。 + + 8.1.0 diff --git a/language/oop5/lazy-objects.xml b/language/oop5/lazy-objects.xml new file mode 100644 index 0000000000..d14fe07615 --- /dev/null +++ b/language/oop5/lazy-objects.xml @@ -0,0 +1,479 @@ + + + + + + レイジーオブジェクト + + + レイジーオブジェクトは、状態が参照または変更されるまで + 初期化が遅延されるオブジェクトです。ユースケースの例として、 + 必要な時だけ初期化される遅延DIコンポーネント、 + 必要な時だけデータを読み込む遅延ORM、 + 必要な時だけ解析を行う遅延JSONパーサーなどがあります。 + + + + レイジーオブジェクトには、ゴーストオブジェクトとバーチャルプロキシの + 2つの戦略があります。以降 "レイジーゴースト"、 + "レイジープロキシ" と呼びます。 + どちらの戦略の場合も、レイジーオブジェクトには + 最初に状態が参照または変更されたときに自動的に呼び出されるイニシャライザまたはファクトリが + 接続されています。抽象的な観点では、レイジーゴーストオブジェクトは + 非レイジーなものと区別がつかず、レイジーであること意識せず使用できます。 + レイジープロキシも同様に透過的ですが、実体を + 参照する際は注意が必要です。プロキシと実インスタンスは異なる実体を + 持つからです。 + + + + レイジーオブジェクトの作成 + + + 任意のユーザー定義クラスやstdClassクラス + (他の内部クラスはサポートされていません)のレイジーインスタンスを作成したり、 + これらのクラスのインスタンスをレイジーにリセットすることが可能です。 + レイジーオブジェクトを作成するエントリーポイントは、 + ReflectionClass::newLazyGhostおよび + ReflectionClass::newLazyProxyメソッドです。 + + + + どちらのメソッドも、オブジェクトの初期化が必要な際に呼び出される関数を + 受け取ります。その関数が要求する動作は、使用する戦略に応じて + 異なります。各メソッドのリファレンスを参照してください。 + + + + レイジーゴーストの作成 + +newLazyGhost(function (Example $object) { + // ここでオブジェクトを初期化 + $object->__construct(1); +}); + +var_dump($lazyObject); +var_dump(get_class($lazyObject)); + +// ここで初期化がトリガーされる +var_dump($lazyObject->prop); +?> +]]> + + &example.outputs; + + +uninitialized(int) +} +string(7) "Example" +Example::__construct +int(1) +]]> + + + + + レイジープロキシの作成 + +newLazyProxy(function (Example $object) { + // 実インスタンスを初期化して返す + return new Example(1); +}); + +var_dump($lazyObject); +var_dump(get_class($lazyObject)); + +// ここで初期化がトリガーされる +var_dump($lazyObject->prop); +?> +]]> + + &example.outputs; + + + uninitialized(int) +} +string(7) "Example" +Example::__construct +int(1) +]]> + + + + + レイジーオブジェクトのプロパティへのアクセスは、初期化をトリガーします + (ReflectionProperty 経由も含む)。 + しかし、特定のプロパティに対してはトリガーしないよう、 + 事前に初期化しておく必要があるかもしれません。 + + + + プロパティを事前に初期化する + +newLazyGhost(function ($post) { + $data = fetch_from_store($post->id); + $post->__construct($data['id'], $data['title'], $data['content']); +}); + +// この行がないと、次のReflectionProperty::setValue()の呼び出しは +// 初期化をトリガーします。 +$reflector->getProperty('id')->skipLazyInitialization($post); +$reflector->getProperty('id')->setValue($post, 123); + +// または、直接以下を使用できます: +$reflector->getProperty('id')->setRawValueWithoutLazyInitialization($post, 123); + +// 事前に設定したidプロパティは初期化をトリガーせずにアクセスできます +var_dump($post->id); +?> +]]> + + + + + ReflectionProperty::skipLazyInitialization および + ReflectionProperty::setRawValueWithoutLazyInitialization + メソッドで、プロパティにアクセスする際の遅延初期化をバイパスできます。 + + + + + レイジーオブジェクトの戦略について + + + レイジーゴーストは、その場で初期化され、 + 初期化後はレイジーでないオブジェクトと区別がつきません。 + この戦略は、オブジェクトのインスタンス化と初期化の両方を + 制御できる場合に適しています。どちらかを制御出来ない場合は + 適していません。 + + + + レイジープロキシは、初期化後、実インスタンスへの + プロキシとして機能します。初期化されたレイジープロキシ上のあらゆる操作は、 + 実インスタンスに転送されます。この戦略は、インスタンスの作成を + 外部に委ねているなど、レイジーゴーストが適さない場合に + 適しています。レイジープロキシはほぼ透過的ですが、インスタンスの実体を + 使用する場合は注意が必要です。プロキシと実インスタンスは異なる + 実体を持つからです。 + + + + + レイジーオブジェクトのライフサイクル + + + オブジェクトは、インスタンス化時に + ReflectionClass::newLazyGhostまたは + ReflectionClass::newLazyProxyを使用して、 + あるいはインスタンス化後に + ReflectionClass::resetAsLazyGhostまたは + ReflectionClass::resetAsLazyProxyを使用して、 + レイジーにできます。その後、以下のいずれかの操作により初期化されます: + + + + + 自動初期化をトリガーする方法でオブジェクトと対話する。 + 初期化トリガーを + 参照してください。 + + + ReflectionProperty::skipLazyInitializationまたは + ReflectionProperty::setRawValueWithoutLazyInitializationを使用して、 + すべてのプロパティを非レイジーとしてマークする。 + + + ReflectionClass::initializeLazyObjectまたは + ReflectionClass::markLazyObjectAsInitializedを + 明示的に呼び出す。 + + + + + すべてのプロパティが非レイジーとしてマークされると、レイジーオブジェクトは + 初期化済とみなされます。従って上記のメソッドは、非レイジーなプロパティがない場合、 + オブジェクトをレイジーとみなしません。 + + + + + 初期化トリガー + + + レイジーオブジェクトは、利用者に対して透過的に設計されているため、 + オブジェクトの状態を参照または変更する通常の操作は、 + その実行の前に自動的に初期化をトリガーします。これには以下の操作が含まれますが、 + これらに限定されません: + + + + + プロパティの読み取りまたは書き込み。 + + + プロパティが設定されているかテスト、またはプロパティの削除。 + + + ReflectionProperty::getValue、 + ReflectionProperty::getRawValue、 + ReflectionProperty::setValue、 + ReflectionProperty::setRawValue + によるプロパティの参照または変更。 + + + ReflectionObject::getProperties、 + ReflectionObject::getProperty、 + get_object_vars + によるプロパティの取得。 + + + Iteratorや + IteratorAggregateを + 実装していないオブジェクトを + foreachでイテレーション。 + + + serialize、 + json_encodeなどでシリアライズ。 + + + クローンの作成。 + + + + + オブジェクトの状態にアクセスしないメソッド呼び出しは初期化を + トリガーしません。同様に、マジックメソッドやフック関数を呼び出す + オブジェクトとの対話も、これらのメソッドや関数がオブジェクトの状態に + アクセスしない限りトリガーしません。 + + + + 初期化をトリガーしない操作 + + + 以下の特定のメソッドや低レベルの操作は、初期化をトリガーせずにレイジー + オブジェクトへのアクセスや変更を可能にします: + + + + + ReflectionProperty::skipLazyInitialization や + ReflectionProperty::setRawValueWithoutLazyInitialization + でプロパティを非レイジーとしてマーク。 + + + get_mangled_object_vars や、 + 配列への変換による + プロパティ内部表現の取得。 + + + ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE + が設定された状態での serialize 。 + ただし __serialize() または + __sleep() が初期化をトリガーしない場合。 + + + ReflectionObject::__toString の呼び出し。 + + + var_dump または + debug_zval_dump 。ただし、 + __debugInfo() が初期化をトリガー + しない場合に限る。 + + + + + + + 初期化シーケンス + + + このセクションでは、初期化がトリガーされたときに実行される操作の順序を + 使用する戦略に応じて説明します。 + + + + ゴーストオブジェクト + + + オブジェクトは非レイジーとしてマークされます。 + + + ReflectionProperty::skipLazyInitializationまたは + ReflectionProperty::setRawValueWithoutLazyInitialization + で初期化されていないプロパティは、デフォルト値があれば + それに設定されます。結果的に、事前に初期化済のプロパティを除き、 + ReflectionClass::newInstanceWithoutConstructor + でと似たオブジェクトになります。 + + + そのオブジェクトをパラメータとして、イニシャライザ関数が呼び出されます。 + この関数は、オブジェクトの状態を初期化することが + 期待されますが、必須ではありません。&null; を返すか、値を返さない必要があります。 + オブジェクトはもはやレイジーではないので、 + 関数はプロパティに直接アクセスできます。 + + + + 初期化後、オブジェクトはレイジーでない場合と + 区別がつきません。 + + + + + プロキシオブジェクト + + + オブジェクトは非レイジーとしてマークされます。 + + + ゴーストオブジェクトとは異なり、この段階でオブジェクトのプロパティは + 変更されません。 + + + オブジェクトがファクトリ関数に入力されます。 + この関数は、互換性のあるクラスの非レイジーなインスタンスを返す必要があります + (ReflectionClass::newLazyProxyを参照)。 + + + 返されたインスタンスは 実インスタンス として参照され、 + プロキシに接続されます。 + + + プロキシのプロパティ値は、 + unset と同等の方法で破棄されます。 + + + + 初期化後、プロキシの任意のプロパティへのアクセスは、 + 実インスタンスへのアクセスと同じ結果をもたらします。 + 宣言済プロパティ、動的プロパティ、存在しないプロパティ、 + ReflectionProperty::skipLazyInitialization や + ReflectionProperty::setRawValueWithoutLazyInitialization で + マークされたプロパティを含む、すべてのプロパティへのアクセスは + 実インスタンスに転送されます。 + + + プロキシオブジェクトが、 + 実インスタンスに置き換えられることはありません。 + + + ファクトリは最初のパラメータとしてプロキシを受け取りますが、 + それを変更することは期待されていません(変更は許可されますが、 + 最終的な初期化ステップ中に失われます)。しかし、プロキシは + 事前に初期化されたプロパティの値、クラス、オブジェクト自体、 + その同一性に基づく決定に使用できます。例えば、イニシャライザは + 実インスタンスを作成する際に初期化されたプロパティの値を利用するかもしれません。 + + + + + 共通の動作 + + + イニシャライザまたはファクトリ関数のスコープと$thisの + コンテキストは変更されず、通常の可視性制約が適用されます。 + + + + 初期化が成功した後、イニシャライザまたはファクトリ関数は + オブジェクトから参照されなくなり、他に参照がなければ + 解放される場合があります。 + + + + イニシャライザが例外をスローした場合、オブジェクトの状態は + 初期化前の状態に戻され、オブジェクトは再びレイジーとマークされます。つまり、 + オブジェクトへの副作用はすべて破棄されます。これは、失敗した場合に + 壊れたインスタンスが生成されてしまうのを防ぎます。ただし、他のオブジェクトへの + 影響など、外部への副作用は元に戻されません。 + + + + + + クローン + + + レイジーオブジェクトをクローンすると、 + クローンが作成される前に初期化がトリガーされ、 + 結果として初期化されたオブジェクトが得られます。 + + + + プロキシオブジェクトの場合、プロキシとその実インスタンスの両方がクローンされ、 + プロキシのクローンが返されます。 + __cloneメソッドは + プロキシではなく実インスタンス上で呼び出されます。 + クローンされたプロキシと実インスタンスは + 初期化時にリンクされるため、クローン後のプロキシへのアクセスは + クローン後の実インスタンスに転送されます。 + + + + この動作により、クローンと元のオブジェクトは独立した状態を持つことが + 保証されます。クローン後に元のオブジェクトまたはそのイニシャライザの状態に + 変更を加えても、クローンには影響しません。実インスタンスのみではなく + 両方をクローンすることで、クローン操作は常に同じクラスのオブジェクトを + 返すことを保証します。 + + + + + デストラクタ + + + レイジーゴーストの場合、オブジェクトが初期化されている場合のみ、 + プロキシの場合、実インスタンスが存在する場合のみ、 + デストラクタが呼び出されます。 + + + + ReflectionClass::resetAsLazyGhostおよび + ReflectionClass::resetAsLazyProxyメソッドは、 + リセットされるオブジェクトのデストラクタを呼び出す場合があります。 + + + diff --git a/reference/reflection/reflectionclass.xml b/reference/reflection/reflectionclass.xml index 73cae67ed4..8194f5a950 100644 --- a/reference/reflection/reflectionclass.xml +++ b/reference/reflection/reflectionclass.xml @@ -1,6 +1,6 @@ - + ReflectionClass クラス @@ -57,6 +57,18 @@ int ReflectionClass::IS_READONLY + + public + const + int + ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE + + + public + const + int + ReflectionClass::SKIP_DESTRUCTOR + &Properties; @@ -141,6 +153,26 @@ + + ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE + + + serializeがレイジーオブジェクトの初期化を + トリガーしないことを示します。 + + + + + + ReflectionClass::SKIP_DESTRUCTOR + + + オブジェクトをレイジーにリセットする時に、 + デストラクタが呼び出されないことを示します。 + + + + diff --git a/reference/reflection/reflectionclass/getlazyinitializer.xml b/reference/reflection/reflectionclass/getlazyinitializer.xml new file mode 100644 index 0000000000..b6c38e6d3d --- /dev/null +++ b/reference/reflection/reflectionclass/getlazyinitializer.xml @@ -0,0 +1,73 @@ + + + + + + + ReflectionClass::getLazyInitializer + レイジーイニシャライザを取得する + + + + &reftitle.description; + + public callablenullReflectionClass::getLazyInitializer + objectobject + + + objectに + アタッチされているレイジーイニシャライザまたはファクトリを取得します。 + + + + + &reftitle.parameters; + + + object + + + イニシャライザを取得する対象のオブジェクト。 + + + + + + + + &reftitle.returnvalues; + + オブジェクトが未初期化のレイジーオブジェクトであればイニシャライザを、 + そうでなければ &null; を返します。 + + + + + &reftitle.seealso; + + レイジーオブジェクト + ReflectionClass::newLazyGhost + + + + + diff --git a/reference/reflection/reflectionclass/initializelazyobject.xml b/reference/reflection/reflectionclass/initializelazyobject.xml new file mode 100644 index 0000000000..c585fae1f5 --- /dev/null +++ b/reference/reflection/reflectionclass/initializelazyobject.xml @@ -0,0 +1,131 @@ + + + + + + + ReflectionClass::initializeLazyObject + レイジーオブジェクトを強制的に初期化する + + + + &reftitle.description; + + public objectReflectionClass::initializeLazyObject + objectobject + + + 指定されたobjectを強制的に初期化します。この + メソッドは、オブジェクトがレイジーでないか、既に初期化されている場合は + 効果がありません。それ以外の場合、初期化は + 初期化シーケンス + の通り進行します。 + + + + + ほとんどの場合、このメソッドを呼び出す必要はありません。なぜなら、 + レイジーオブジェクトはその状態が参照または変更されたときに + 自動的に初期化されるからです。 + + + + + + &reftitle.parameters; + + + object + + + 初期化するオブジェクト。 + + + + + + + + &reftitle.returnvalues; + + objectがレイジープロキシであれば、 + その実インスタンスを、そうでなければ object自身を返します。 + + + + + &reftitle.examples; + + 基本的な使用法 + +newLazyGhost(function ($object) { + echo "Initializer called\n"; + $object->__construct(1); +}); + +var_dump($object); + +$reflector->initializeLazyObject($object); + +var_dump($object); +?> +]]> + + &example.outputs; + + + uninitialized(int) +} +Initializer called +object(Example)#3 (1) { + ["prop"]=> + int(1) +} +]]> + + + + + + &reftitle.seealso; + + レイジーオブジェクト + ReflectionClass::newLazyGhost + ReflectionClass::markLazyObjectAsInitialized + ReflectionClass::isUninitializedLazyObject + + + + + diff --git a/reference/reflection/reflectionclass/isuninitializedlazyobject.xml b/reference/reflection/reflectionclass/isuninitializedlazyobject.xml new file mode 100644 index 0000000000..f33a72b13b --- /dev/null +++ b/reference/reflection/reflectionclass/isuninitializedlazyobject.xml @@ -0,0 +1,114 @@ + + + + + + + ReflectionClass::isUninitializedLazyObject + オブジェクトがレイジーで未初期化かどうかを調べる + + + + &reftitle.description; + + public boolReflectionClass::isUninitializedLazyObject + objectobject + + + オブジェクトがレイジーで未初期化かどうかを調べます。 + + + + + &reftitle.parameters; + + + object + + + 調べるオブジェクト。 + + + + + + + + &reftitle.returnvalues; + + object が未初期化のレイジーオブジェクトであれば &true; を、 + そうでなければ &false; を返します。 + + + + + &reftitle.examples; + + 基本的な使用法 + +newLazyGhost(function ($object) { + echo "Initializer called\n"; + $object->__construct(1); +}); + +var_dump($reflector->isUninitializedLazyObject($object)); + +var_dump($object->prop); + +var_dump($reflector->isUninitializedLazyObject($object)); +?> +]]> + + &example.outputs; + + + + + + + + &reftitle.seealso; + + レイジーオブジェクト + ReflectionClass::newLazyGhost + ReflectionClass::markLazyObjectAsInitialized + ReflectionClass::initializeLazyObject + + + + + diff --git a/reference/reflection/reflectionclass/marklazyobjectasinitialized.xml b/reference/reflection/reflectionclass/marklazyobjectasinitialized.xml new file mode 100644 index 0000000000..389965842b --- /dev/null +++ b/reference/reflection/reflectionclass/marklazyobjectasinitialized.xml @@ -0,0 +1,197 @@ + + + + + + + ReflectionClass::markLazyObjectAsInitialized + イニシャライザまたはファクトリを呼び出さずレイジーオブジェクトを初期化済みとしてマークする + + + + &reftitle.description; + + public objectReflectionClass::markLazyObjectAsInitialized + objectobject + + + イニシャライザまたはファクトリを呼び出さずレイジーオブジェクトを + 初期化済みとしてマークします。object がレイジーでないか、 + すでに初期化されている場合、このメソッドは効果がありません。 + + + このメソッド動作は、object のレイジー戦略に関わらず、 + 初期化シーケンス + においてゴーストオブジェクトに対して説明されたものとほぼ同じですが、 + イニシャライザが呼び出されない点を除きます。 + その後、オブジェクトは、ReflectionProperty::setRawValueWithoutLazyInitialization または + ReflectionProperty::skipLazyInitialization で + 既に初期化されたプロパティの値を除いて、 + ReflectionClass::newInstanceWithoutConstructor で作成された、 + 元々レイジーでなかったオブジェクトと区別がつかなくなります。 + + + + + &reftitle.parameters; + + + object + + + 初期化済みとしてマークするオブジェクト。 + + + + + + + + &reftitle.returnvalues; + + object を返します。 + + + + + &reftitle.examples; + + 未初期化のレイジーオブジェクトを初期化済みとしてマークする + +newLazyGhost(function ($object) { + echo "Initializer called\n"; + $object->prop1 = 'initialized'; +}); + +$reflector->getProperty('prop1') + ->setRawValueWithoutLazyInitialization($object, 'prop1 value'); + +var_dump($object); + +$reflector->markLazyObjectAsInitialized($object); + +var_dump($object); +?> +]]> + + &example.outputs; + + + string(11) "prop1 value" + ["prop2"]=> + uninitialized(string) + ["prop3"]=> + uninitialized(string) +} +object(Example)#3 (2) { + ["prop1"]=> + string(11) "prop1 value" + ["prop2"]=> + uninitialized(string) + ["prop3"]=> + string(13) "default value" +} +]]> + + + + 既に初期化されたオブジェクトを初期化済みとしてマークする + +newLazyGhost(function ($object) { + echo "Initializer called\n"; + $object->prop1 = 'initialized'; +}); + +$reflector->getProperty('prop1') + ->setRawValueWithoutLazyInitialization($object, 'prop1 value'); + +var_dump($object->prop3); +var_dump($object); + +$reflector->markLazyObjectAsInitialized($object); + +var_dump($object); +?> + ]]> + + &example.outputs; + + + string(11) "initialized" + ["prop2"]=> + uninitialized(string) + ["prop3"]=> + string(13) "default value" +} +object(Example)#3 (2) { + ["prop1"]=> + string(11) "initialized" + ["prop2"]=> + uninitialized(string) + ["prop3"]=> + string(13) "default value" +} +]]> + + + + + + &reftitle.seealso; + + レイジーオブジェクト + ReflectionClass::newLazyGhost + ReflectionClass::initializeLazyObject + ReflectionClass::isUninitializedLazyObject + + + + + diff --git a/reference/reflection/reflectionclass/newlazyghost.xml b/reference/reflection/reflectionclass/newlazyghost.xml new file mode 100644 index 0000000000..54cbbeff7d --- /dev/null +++ b/reference/reflection/reflectionclass/newlazyghost.xml @@ -0,0 +1,188 @@ + + + + + + + ReflectionClass::newLazyGhost + 新しいレイジーゴーストインスタンスを作成する + + + + &reftitle.description; + + public object ReflectionClass::newLazyGhost + callableinitializer + intoptions0 + + + クラスの新しいレイジーゴーストインスタンスを作成し、 + initializer をアタッチします。コンストラクタは呼び出されず、 + プロパティはデフォルト値に設定されません。オブジェクトの状態を + 初めて参照または変更する時に、 + initializerをにより自動的に初期化されます。 + 初期化トリガーおよび + 初期化シーケンス + を参照してください。 + + + + + &reftitle.parameters; + + + initializer + + + イニシャライザは以下のシグネチャを持つコールバックです: + + + + voidinitializer + objectobject + + + + object + + + 初期化されるobject。この時点では、 + オブジェクトはもはやレイジーとしてマークされておらず、 + アクセスしても再び初期化がトリガーされることはありません。 + + + + + + + initializer関数は &null; を返すか、 + 値を返さない必要があります。 + + + + + options + + + optionsには以下のフラグを組み合わせて + 指定できます: + + + + ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE + + + + デフォルトでは、レイジーオブジェクトのシリアライズは + 初期化がトリガーされます。このフラグを設定すると、 + 初期化せずにシリアライズできるようになります。 + + + + + + + + + + + + &reftitle.returnvalues; + + レイジーゴーストインスタンスを返します。オブジェクトにプロパティがない場合、または + そのプロパティがすべてstaticまたはvirtualの場合、通常の(レイジーではない)インスタンスが + 返されます。 + レイジーオブジェクトの + ライフサイクルも参照してください。 + + + + + &reftitle.errors; + + クラスが内部クラスであるか、stdClassを除く内部クラスを + 拡張している場合、Errorをスローします。 + + + + + &reftitle.examples; + + 基本的な使用法 + +newLazyGhost(function (Example $object) { + $object->__construct(1); +}); + +var_dump($object); +var_dump($object instanceof Example); + +// 初期化をトリガーし、その後プロパティを取得します +var_dump($object->prop); + +?> +]]> + + &example.outputs; + + + uninitialized(int) +} +bool(true) +Example::__construct +int(1) +]]> + + + + + + &reftitle.seealso; + + レイジーオブジェクト + ReflectionClass::newLazyProxy + ReflectionClass::newInstanceWithoutConstructor + ReflectionClass::resetAsLazyGhost + ReflectionClass::markLazyObjectAsInitialized + ReflectionClass::initializeLazyObject + ReflectionClass::isUninitializedLazyObject + ReflectionProperty::setRawValueWithoutLazyInitialization + ReflectionProperty::skipLazyInitialization + ReflectionProperty::isLazy + + + + + + diff --git a/reference/reflection/reflectionclass/newlazyproxy.xml b/reference/reflection/reflectionclass/newlazyproxy.xml new file mode 100644 index 0000000000..a64bc5827a --- /dev/null +++ b/reference/reflection/reflectionclass/newlazyproxy.xml @@ -0,0 +1,181 @@ + + + + + + + ReflectionClass::newLazyProxy + 新しいレイジープロキシインスタンスを作成する + + + + &reftitle.description; + + public objectReflectionClass::newLazyProxy + callablefactory + intoptions0 + + + クラスの新しいレイジープロキシインスタンスを作成し、 + factory をアタッチします。コンストラクタは呼び出されず、 + プロパティはデフォルト値に設定されません。プロキシの状態を + 初めて参照または変更する時に、 + ファクトリ関数により実インスタンスが初期化され、 + プロキシにアタッチされます。その後、プロキシとのすべての対話は + 実インスタンスに転送されます。 + 初期化トリガーおよび + 初期化シーケンス + を参照してください。 + + + + + &reftitle.parameters; + + + factory + + + ファクトリは以下のシグネチャを持つコールバックです: + + + + objectfactory + objectobject + + + + object + + + 初期化されるobject。この時点では、 + オブジェクトはもはやレイジーとしてマークされておらず、 + アクセスしても再び初期化がトリガーされることはありません。 + + + + + + + ファクトリ関数は、実インスタンスとして参照される + オブジェクトを返す必要があり、それがプロキシにアタッチされます。 + この実インスタンスはレイジーであってはならず、 + プロキシ自体でもあってはなりません。もし実インスタンスが + プロキシと同じクラスでない場合、プロキシのクラスは実インスタンスのクラスの + サブクラスでなければならず、追加のプロパティを持ってはならず、 + __destruct__cloneメソッドを + オーバーライドしてはいけまさん。 + + + + + + + + + + + + + &reftitle.returnvalues; + + レイジープロキシインスタンスを返します。オブジェクトにプロパティがない場合、または + そのプロパティがすべてstaticまたはvirtualの場合、通常の(レイジーではない)インスタンスが + 返されます。 + レイジーオブジェクトの + ライフサイクルも参照してください。 + + + + + + + + + &reftitle.examples; + + 基本的な使用法 + +newLazyProxy(function (Example $object) { + $realInstance = new Example(1); + return $realInstance; +}); + +var_dump($object); +var_dump($object instanceof Example); + +// 初期化をトリガーし、プロパティの取得を実インスタンスに転送します +var_dump($object->prop); + +var_dump($object); +?> +]]> + + &example.outputs; + + + uninitialized(int) +} +bool(true) +Example::__construct +int(1) +lazy proxy object(Example)#3 (1) { + ["instance"]=> + object(Example)#4 (1) { + ["prop"]=> + int(1) + } +} +]]> + + + + + + &reftitle.seealso; + + レイジーオブジェクト + ReflectionClass::newLazyGhost + ReflectionClass::newInstanceWithoutConstructor + ReflectionClass::resetAsLazyProxy + ReflectionClass::markLazyObjectAsInitialized + ReflectionClass::initializeLazyObject + ReflectionClass::isUninitializedLazyObject + ReflectionProperty::setRawValueWithoutLazyInitialization + ReflectionProperty::skipLazyInitialization + ReflectionProperty::isLazy + + + + + diff --git a/reference/reflection/reflectionclass/resetaslazyghost.xml b/reference/reflection/reflectionclass/resetaslazyghost.xml new file mode 100644 index 0000000000..9ef8163c35 --- /dev/null +++ b/reference/reflection/reflectionclass/resetaslazyghost.xml @@ -0,0 +1,170 @@ + + + + + + + ReflectionClass::resetAsLazyGhost + オブジェクトをリセットしてレイジーとしてマークする + + + + &reftitle.description; + + public voidReflectionClass::resetAsLazyGhost + objectobject + callableinitializer + intoptions0 + + + 既存のobjectをリセットし、レイジーとしてマークします。 + + + オブジェクトのデストラクタが存在する場合、 + ReflectionClass::SKIP_DESTRUCTORフラグが指定されていない限り、 + デストラクタが呼び出されます。特殊なケースとして、オブジェクトが初期済のプロキシの場合、 + 実インスタンスはプロキシから切り離されます。実インスタンスが他で参照されていない場合、 + SKIP_DESTRUCTORフラグに関係なく、 + そのデストラクタが呼び出されます。 + + + 動的プロパティは削除され、クラスで宣言されたプロパティの値は + unset と同等の方法で破棄され、 + レイジーとしてマークされます。これは、オブジェクトが追加のプロパティを持つ + サブクラスのインスタンスである場合、これらのプロパティは変更されず、 + レイジーにもならないことを意味します。 + 読み取り専用プロパティも、 + finalであるかクラス自体がfinalである場合、 + 変更されず、レイジーにもなりません。 + + + レイジーとしてマークされたプロパティがない場合、オブジェクトはレイジーとしてマークされません。 + レイジーオブジェクトのライフサイクル + も参照してください。 + + + それ以外の場合、このメソッドを呼び出した後、 + オブジェクトの動作は + ReflectionClass::newLazyGhostによって作成されたオブジェクトと同じになります + (上記で説明したサブクラスと読み取り専用プロパティを除く)。 + + + オブジェクトは他のものに置き換えられず、その同一性は変わりません。 + spl_object_id、 + spl_object_hash、 + SplObjectStorage、 + WeakMap、 + WeakReference、または + 一致演算子 + (===)などの機能は影響を受けません。 + + + + + &reftitle.parameters; + + + object + + + 非レイジーなオブジェクト、または初期化されたレイジーオブジェクト。 + + + + + initializer + + + ReflectionClass::newLazyGhost + と同じシグネチャと目的を持つイニシャライザコールバック。 + + + + + options + + + optionsには + 以下のフラグを組み合わせて指定できます: + + + + ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE + + + + デフォルトでは、レイジーオブジェクトのシリアライズは + 初期化がトリガーされます。このフラグを設定すると、 + 初期化せずにシリアライズできるようになります。 + + + + + + ReflectionClass::SKIP_DESTRUCTOR + + + + デフォルトでは、オブジェクトをレイジーにする前に、そのデストラクタが(存在すれば) + 呼び出されます。これは、オブジェクト内の既存の状態に関する安全性を提供します。 + このフラグはその動作を無効にし、デストラクタを呼び出さずにオブジェクトを + レイジーとしてリセットできるようにします。 + + + + + + + + + + + + &reftitle.returnvalues; + + &return.void; + + + + + &reftitle.errors; + + オブジェクトがレイジーで未初期化の場合、ReflectionExceptionを + スローします。 + + + オブジェクトが初期化中である場合、またはforeachで + プロパティが反復処理されている場合、Errorを + スローします。 + + + + + &reftitle.seealso; + + ReflectionClass::newLazyGhost + ReflectionClass::resetAsLazyProxy + + + + + diff --git a/reference/reflection/reflectionclass/resetaslazyproxy.xml b/reference/reflection/reflectionclass/resetaslazyproxy.xml new file mode 100644 index 0000000000..197cc3f14a --- /dev/null +++ b/reference/reflection/reflectionclass/resetaslazyproxy.xml @@ -0,0 +1,100 @@ + + + + + + + ReflectionClass::resetAsLazyProxy + オブジェクトをリセットしてレイジーとしてマークする + + + + &reftitle.description; + + public voidReflectionClass::resetAsLazyProxy + objectobject + callablefactory + intoptions0 + + + このメソッドの動作は、 + ReflectionClass::resetAsLazyGhostと同じですが、 + プロキシ戦略を使用します。 + + + object自体がプロキシになります。 + ReflectionClass::resetAsLazyGhostと同様に、 + オブジェクトは他のものに置き換えられず、初期化後もその同一性は + 変わりません。プロキシと実インスタンスは別々のオブジェクトであり、 + 別々の実体を持ちます。 + + + + + &reftitle.parameters; + + + object + + + 非レイジーなオブジェクト、または初期化されたレイジーオブジェクト。 + + + + + factory + + + ReflectionClass::newLazyProxyと + 同じシグネチャと目的を持つファクトリコールバック。 + + + + + + + + + + + + + &reftitle.returnvalues; + + &return.void; + + + + + + + + + &reftitle.seealso; + + ReflectionClass::newLazyProxy + ReflectionClass::resetAsLazyGhost + + + + + diff --git a/reference/reflection/reflectionproperty/islazy.xml b/reference/reflection/reflectionproperty/islazy.xml new file mode 100644 index 0000000000..ce74d88928 --- /dev/null +++ b/reference/reflection/reflectionproperty/islazy.xml @@ -0,0 +1,67 @@ + + + + ReflectionProperty::isLazy + プロパティがレイジーであるかどうかを調べる + + + + &reftitle.description; + + public boolReflectionProperty::isLazy + objectobject + + + プロパティがレイジーであるかどうかを調べます。 + + + + + &reftitle.parameters; + + + object + + + プロパティを調べる対象のオブジェクト。 + + + + + + + + &reftitle.returnvalues; + + プロパティがレイジーであれば &true; を、そうでなければ &false; を返します。 + + + + + &reftitle.seealso; + + レイジーオブジェクト + + + + + diff --git a/reference/reflection/reflectionproperty/setrawvaluewithoutlazyinitialization.xml b/reference/reflection/reflectionproperty/setrawvaluewithoutlazyinitialization.xml new file mode 100644 index 0000000000..5d2a6f1222 --- /dev/null +++ b/reference/reflection/reflectionproperty/setrawvaluewithoutlazyinitialization.xml @@ -0,0 +1,90 @@ + + + + + + + ReflectionProperty::setRawValueWithoutLazyInitialization + 遅延初期化をトリガーせず生のプロパティ値を設定する + + + + &reftitle.description; + + public voidReflectionProperty::setRawValueWithoutLazyInitialization + objectobject + mixednullvalue + + + 遅延初期化をトリガーせず、フック関数も呼び出さずに、 + プロパティの生の値を設定または変更します。 + プロパティは非レイジーとしてマークされ、その後は + 遅延初期化をトリガーせずにアクセスできます。 + プロパティはダイナミック、static、またはvirtualであってはならず、オブジェクトは + ユーザー定義クラスまたはstdClassのインスタンスでなければなりません。 + + + これが最後のレイジープロパティであった場合、オブジェクトは非レイジーとしてマークされ、 + イニシャライザまたはファクトリ関数が切り離されます。 + + + + + &reftitle.parameters; + + + object + + + プロパティを変更する対象のオブジェクト。 + + + + + value + + + 新しい値。 + + + + + + + + &reftitle.returnvalues; + + &return.void; + + + + + &reftitle.seealso; + + レイジーオブジェクト + ReflectionProperty::skipLazyInitialization + ReflectionClass::newLazyGhost + + + + + diff --git a/reference/reflection/reflectionproperty/skiplazyinitialization.xml b/reference/reflection/reflectionproperty/skiplazyinitialization.xml new file mode 100644 index 0000000000..5b5ed1e674 --- /dev/null +++ b/reference/reflection/reflectionproperty/skiplazyinitialization.xml @@ -0,0 +1,80 @@ + + + + + + + ReflectionProperty::skipLazyInitialization + プロパティを非レイジーとしてマークする + + + + &reftitle.description; + + public voidReflectionProperty::skipLazyInitialization + objectobject + + + プロパティを非レイジーとしてマークし、遅延初期化をトリガーせずに + 直接アクセスできるようにします。プロパティは、デフォルト値があれば + それに初期化されます。 + プロパティはダイナミック、static、またはvirtualであってはならず、オブジェクトは + ユーザー定義クラスまたはstdClassのインスタンスでなければなりません。 + + + これが最後のレイジープロパティであった場合、オブジェクトは非レイジーとしてマークされ、 + イニシャライザまたはファクトリ関数が切り離されます。 + + + + + &reftitle.parameters; + + + object + + + プロパティをマークする対象のオブジェクト。 + + + + + + + + &reftitle.returnvalues; + + &return.void; + + + + + &reftitle.seealso; + + レイジーオブジェクト + ReflectionProperty::setRawValueWithoutLazyInitialization + ReflectionClass::newLazyGhost + + + + +