<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/language.oop5.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ja',
  ),
  'this' => 
  array (
    0 => 'language.oop5.lazy-objects.php',
    1 => 'レイジーオブジェクト',
    2 => 'レイジーオブジェクト',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'クラスとオブジェクト',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.variance.php',
    1 => '共変性と反変性',
  ),
  'next' => 
  array (
    0 => 'language.oop5.changelog.php',
    1 => '変更履歴',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ja',
    'path' => 'language/oop5/lazy-objects.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.oop5.lazy-objects" class="sect1">
 <h2 class="title">レイジーオブジェクト</h2>

 <p class="simpara">
  レイジーオブジェクトは、状態が参照または変更されるまで
  初期化が遅延されるオブジェクトです。ユースケースの例として、
  必要な時だけ初期化される遅延DIコンポーネント、
  必要な時だけデータを読み込む遅延<abbr>ORM</abbr>、
  必要な時だけ解析を行う遅延JSONパーサーなどがあります。
 </p>

 <p class="simpara">
  レイジーオブジェクトには、ゴーストオブジェクトとバーチャルプロキシの
  2つの戦略があります。以降 &quot;レイジーゴースト&quot;、
  &quot;レイジープロキシ&quot; と呼びます。
  どちらの戦略の場合も、レイジーオブジェクトには
  最初に状態が参照または変更されたときに自動的に呼び出されるイニシャライザまたはファクトリが
  接続されています。抽象的な観点では、レイジーゴーストオブジェクトは
  非レイジーなものと区別がつかず、レイジーであること意識せず使用できます。
  レイジープロキシも同様に透過的ですが、実体を
  参照する際は注意が必要です。プロキシと実インスタンスは異なる実体を
  持つからです。
 </p>

 <blockquote class="note"><p><strong class="note">注意</strong>: 
  <strong>バージョン情報</strong><br />
  <span class="simpara">
   レイジーオブジェクトは、PHP 8.4 で実装されました。
  </span>
 </p></blockquote>

 <div class="sect2" id="language.oop5.lazy-objects.creation">
  <h3 class="title">レイジーオブジェクトの作成</h3>

  <p class="simpara">
   任意のユーザー定義クラスや<span class="classname"><a href="class.stdclass.php" class="classname">stdClass</a></span>クラス
   （他の内部クラスはサポートされていません）のレイジーインスタンスを作成したり、
   これらのクラスのインスタンスをレイジーにリセットすることが可能です。
   レイジーオブジェクトを作成するエントリーポイントは、
   <span class="methodname"><a href="reflectionclass.newlazyghost.php" class="methodname">ReflectionClass::newLazyGhost()</a></span>および
   <span class="methodname"><a href="reflectionclass.newlazyproxy.php" class="methodname">ReflectionClass::newLazyProxy()</a></span>メソッドです。
  </p>

  <p class="simpara">
   どちらのメソッドも、オブジェクトの初期化が必要な際に呼び出される関数を
   受け取ります。その関数が要求する動作は、使用する戦略に応じて
   異なります。各メソッドのリファレンスを参照してください。
  </p>

  <div class="example" id="example-1">
   <p><strong>例1 レイジーゴーストの作成</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Example<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">(public </span><span style="color: #0000BB">int $prop</span><span style="color: #007700">)<br />    {<br />        echo </span><span style="color: #0000BB">__METHOD__</span><span style="color: #007700">, </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$reflector </span><span style="color: #007700">= new </span><span style="color: #0000BB">ReflectionClass</span><span style="color: #007700">(</span><span style="color: #0000BB">Example</span><span style="color: #007700">::class);<br /></span><span style="color: #0000BB">$lazyObject </span><span style="color: #007700">= </span><span style="color: #0000BB">$reflector</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">newLazyGhost</span><span style="color: #007700">(function (</span><span style="color: #0000BB">Example $object</span><span style="color: #007700">) {<br />    </span><span style="color: #FF8000">// ここでオブジェクトを初期化<br />    </span><span style="color: #0000BB">$object</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">__construct</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">);<br />});<br /><br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$lazyObject</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">get_class</span><span style="color: #007700">(</span><span style="color: #0000BB">$lazyObject</span><span style="color: #007700">));<br /><br /></span><span style="color: #FF8000">// ここで初期化がトリガーされる<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$lazyObject</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prop</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>上の例の出力は以下となります。</p></div>
   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
lazy ghost object(Example)#3 (0) {
[&quot;prop&quot;]=&gt;
uninitialized(int)
}
string(7) &quot;Example&quot;
Example::__construct
int(1)
</pre></div>
   </div>
  </div>

  <div class="example" id="example-2">
   <p><strong>例2 レイジープロキシの作成</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Example<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">(public </span><span style="color: #0000BB">int $prop</span><span style="color: #007700">)<br />    {<br />        echo </span><span style="color: #0000BB">__METHOD__</span><span style="color: #007700">, </span><span style="color: #DD0000">"\n"</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$reflector </span><span style="color: #007700">= new </span><span style="color: #0000BB">ReflectionClass</span><span style="color: #007700">(</span><span style="color: #0000BB">Example</span><span style="color: #007700">::class);<br /></span><span style="color: #0000BB">$lazyObject </span><span style="color: #007700">= </span><span style="color: #0000BB">$reflector</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">newLazyProxy</span><span style="color: #007700">(function (</span><span style="color: #0000BB">Example $object</span><span style="color: #007700">) {<br />    </span><span style="color: #FF8000">// 実インスタンスを初期化して返す<br />    </span><span style="color: #007700">return new </span><span style="color: #0000BB">Example</span><span style="color: #007700">(</span><span style="color: #0000BB">1</span><span style="color: #007700">);<br />});<br /><br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$lazyObject</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">get_class</span><span style="color: #007700">(</span><span style="color: #0000BB">$lazyObject</span><span style="color: #007700">));<br /><br /></span><span style="color: #FF8000">// ここで初期化がトリガーされる<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$lazyObject</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prop</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

   <div class="example-contents"><p>上の例の出力は以下となります。</p></div>
   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
lazy proxy object(Example)#3 (0) {
  [&quot;prop&quot;]=&gt;
  uninitialized(int)
}
string(7) &quot;Example&quot;
Example::__construct
int(1)
</pre></div>
   </div>
  </div>

  <p class="simpara">
   レイジーオブジェクトのプロパティへのアクセスは、初期化をトリガーします
   (<span class="classname"><a href="class.reflectionproperty.php" class="classname">ReflectionProperty</a></span> 経由も含む)。
   しかし、特定のプロパティに対してはトリガーしないよう、
   事前に初期化しておく必要があるかもしれません。
  </p>

  <div class="example" id="example-3">
   <p><strong>例3 プロパティを事前に初期化する</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /></span><span style="color: #007700">class </span><span style="color: #0000BB">BlogPost<br /></span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">(<br />        public </span><span style="color: #0000BB">int $id</span><span style="color: #007700">,<br />        public </span><span style="color: #0000BB">string $title</span><span style="color: #007700">,<br />        public </span><span style="color: #0000BB">string $content</span><span style="color: #007700">,<br />    ) { }<br />}<br /><br /></span><span style="color: #0000BB">$reflector </span><span style="color: #007700">= new </span><span style="color: #0000BB">ReflectionClass</span><span style="color: #007700">(</span><span style="color: #0000BB">BlogPost</span><span style="color: #007700">::class);<br /><br /></span><span style="color: #0000BB">$post </span><span style="color: #007700">= </span><span style="color: #0000BB">$reflector</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">newLazyGhost</span><span style="color: #007700">(function (</span><span style="color: #0000BB">$post</span><span style="color: #007700">) {<br />    </span><span style="color: #0000BB">$data </span><span style="color: #007700">= </span><span style="color: #0000BB">fetch_from_store</span><span style="color: #007700">(</span><span style="color: #0000BB">$post</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">id</span><span style="color: #007700">);<br />    </span><span style="color: #0000BB">$post</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">__construct</span><span style="color: #007700">(</span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'id'</span><span style="color: #007700">], </span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'title'</span><span style="color: #007700">], </span><span style="color: #0000BB">$data</span><span style="color: #007700">[</span><span style="color: #DD0000">'content'</span><span style="color: #007700">]);<br />});<br /><br /></span><span style="color: #FF8000">// この行がないと、次のReflectionProperty::setValue()の呼び出しは<br />// 初期化をトリガーします。<br /></span><span style="color: #0000BB">$reflector</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getProperty</span><span style="color: #007700">(</span><span style="color: #DD0000">'id'</span><span style="color: #007700">)-&gt;</span><span style="color: #0000BB">skipLazyInitialization</span><span style="color: #007700">(</span><span style="color: #0000BB">$post</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$reflector</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getProperty</span><span style="color: #007700">(</span><span style="color: #DD0000">'id'</span><span style="color: #007700">)-&gt;</span><span style="color: #0000BB">setValue</span><span style="color: #007700">(</span><span style="color: #0000BB">$post</span><span style="color: #007700">, </span><span style="color: #0000BB">123</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">// または、直接以下を使用できます:<br /></span><span style="color: #0000BB">$reflector</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getProperty</span><span style="color: #007700">(</span><span style="color: #DD0000">'id'</span><span style="color: #007700">)-&gt;</span><span style="color: #0000BB">setRawValueWithoutLazyInitialization</span><span style="color: #007700">(</span><span style="color: #0000BB">$post</span><span style="color: #007700">, </span><span style="color: #0000BB">123</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">// 事前に設定したidプロパティは初期化をトリガーせずにアクセスできます<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$post</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">id</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>

  <p class="simpara">
   <span class="methodname"><a href="reflectionproperty.skiplazyinitialization.php" class="methodname">ReflectionProperty::skipLazyInitialization()</a></span> および
   <span class="methodname"><a href="reflectionproperty.setrawvaluewithoutlazyinitialization.php" class="methodname">ReflectionProperty::setRawValueWithoutLazyInitialization()</a></span>
   メソッドで、プロパティにアクセスする際の遅延初期化をバイパスできます。
  </p>
 </div>

 <div class="sect2" id="language.oop5.lazy-objects.patterns">
  <h3 class="title">レイジーオブジェクトの戦略について</h3>

  <p class="simpara">
   <em>レイジーゴースト</em>は、その場で初期化され、
   初期化後はレイジーでないオブジェクトと区別がつきません。
   この戦略は、オブジェクトのインスタンス化と初期化の両方を
   制御できる場合に適しています。どちらかを制御出来ない場合は
   適していません。
  </p>

  <p class="simpara">
   <em>レイジープロキシ</em>は、初期化後、実インスタンスへの
   プロキシとして機能します。初期化されたレイジープロキシ上のあらゆる操作は、
   実インスタンスに転送されます。この戦略は、インスタンスの作成を
   外部に委ねているなど、レイジーゴーストが適さない場合に
   適しています。レイジープロキシはほぼ透過的ですが、インスタンスの実体を
   使用する場合は注意が必要です。プロキシと実インスタンスは異なる
   実体を持つからです。
  </p>
 </div>

 <div class="sect2" id="language.oop5.lazy-objects.lifecycle">
  <h3 class="title">レイジーオブジェクトのライフサイクル</h3>

  <p class="simpara">
   オブジェクトは、インスタンス化時に
   <span class="methodname"><a href="reflectionclass.newlazyghost.php" class="methodname">ReflectionClass::newLazyGhost()</a></span>または
   <span class="methodname"><a href="reflectionclass.newlazyproxy.php" class="methodname">ReflectionClass::newLazyProxy()</a></span>を使用して、
   あるいはインスタンス化後に
   <span class="methodname"><a href="reflectionclass.resetaslazyghost.php" class="methodname">ReflectionClass::resetAsLazyGhost()</a></span>または
   <span class="methodname"><a href="reflectionclass.resetaslazyproxy.php" class="methodname">ReflectionClass::resetAsLazyProxy()</a></span>を使用して、
   レイジーにできます。その後、以下のいずれかの操作により初期化されます:
  </p>

  <ul class="simplelist">
   <li>
    自動初期化をトリガーする方法でオブジェクトと対話する。
    <a href="language.oop5.lazy-objects.php#language.oop5.lazy-objects.initialization-triggers" class="link">初期化トリガー</a>を
    参照してください。
   </li>
   <li>
    <span class="methodname"><a href="reflectionproperty.skiplazyinitialization.php" class="methodname">ReflectionProperty::skipLazyInitialization()</a></span>または
    <span class="methodname"><a href="reflectionproperty.setrawvaluewithoutlazyinitialization.php" class="methodname">ReflectionProperty::setRawValueWithoutLazyInitialization()</a></span>を使用して、
    すべてのプロパティを非レイジーとしてマークする。
   </li>
   <li>
    <span class="methodname"><a href="reflectionclass.initializelazyobject.php" class="methodname">ReflectionClass::initializeLazyObject()</a></span>または
    <span class="methodname"><a href="reflectionclass.marklazyobjectasinitialized.php" class="methodname">ReflectionClass::markLazyObjectAsInitialized()</a></span>を
    明示的に呼び出す。
   </li>
  </ul>

  <p class="simpara">
   すべてのプロパティが非レイジーとしてマークされると、レイジーオブジェクトは
   初期化済とみなされます。従って上記のメソッドは、非レイジーなプロパティがない場合、
   オブジェクトをレイジーとみなしません。
  </p>
 </div>

 <div class="sect2" id="language.oop5.lazy-objects.initialization-triggers">
  <h3 class="title">初期化トリガー</h3>

  <p class="simpara">
   レイジーオブジェクトは、利用者に対して透過的に設計されているため、
   オブジェクトの状態を参照または変更する通常の操作は、
   その実行の前に自動的に初期化をトリガーします。これには以下の操作が含まれますが、
   これらに限定されません:
  </p>

  <ul class="simplelist">
   <li>
    プロパティの読み取りまたは書き込み。
   </li>
   <li>
    プロパティが設定されているかテスト、またはプロパティの削除。
   </li>
   <li>
    <span class="methodname"><a href="reflectionproperty.getvalue.php" class="methodname">ReflectionProperty::getValue()</a></span>、
    <span class="methodname"><a href="reflectionproperty.getrawvalue.php" class="methodname">ReflectionProperty::getRawValue()</a></span>、
    <span class="methodname"><a href="reflectionproperty.setvalue.php" class="methodname">ReflectionProperty::setValue()</a></span>、
    <span class="methodname"><a href="reflectionproperty.setrawvalue.php" class="methodname">ReflectionProperty::setRawValue()</a></span>
    によるプロパティの参照または変更。
   </li>
   <li>
    <span class="methodname"><strong>ReflectionObject::getProperties()</strong></span>、
    <span class="methodname"><strong>ReflectionObject::getProperty()</strong></span>、
    <span class="function"><a href="function.get-object-vars.php" class="function">get_object_vars()</a></span>
    によるプロパティの取得。
   </li>
   <li>
    <span class="interfacename"><a href="class.iterator.php" class="interfacename">Iterator</a></span>や
    <span class="interfacename"><a href="class.iteratoraggregate.php" class="interfacename">IteratorAggregate</a></span>を
    実装していないオブジェクトを
    <a href="control-structures.foreach.php" class="link">foreach</a>でイテレーション。
   </li>
   <li>
    <span class="function"><a href="function.serialize.php" class="function">serialize()</a></span>、
    <span class="function"><a href="function.json-encode.php" class="function">json_encode()</a></span>などでシリアライズ。
   </li>
   <li>
    <a href="language.oop5.lazy-objects.php#language.oop5.lazy-objects.cloning" class="link">クローン</a>の作成。
   </li>
  </ul>

  <p class="simpara">
   オブジェクトの状態にアクセスしないメソッド呼び出しは初期化を
   トリガーしません。同様に、マジックメソッドやフック関数を呼び出す
   オブジェクトとの対話も、これらのメソッドや関数がオブジェクトの状態に
   アクセスしない限りトリガーしません。
  </p>

  <div class="sect3">
   <h4 class="title">初期化をトリガーしない操作</h4>

   <p class="simpara">
    以下の特定のメソッドや低レベルの操作は、初期化をトリガーせずにレイジー
    オブジェクトへのアクセスや変更を可能にします:
   </p>

   <ul class="simplelist">
    <li>
     <span class="methodname"><a href="reflectionproperty.skiplazyinitialization.php" class="methodname">ReflectionProperty::skipLazyInitialization()</a></span> や
     <span class="methodname"><a href="reflectionproperty.setrawvaluewithoutlazyinitialization.php" class="methodname">ReflectionProperty::setRawValueWithoutLazyInitialization()</a></span>
     でプロパティを非レイジーとしてマーク。
    </li>
    <li>
     <span class="function"><a href="function.get-mangled-object-vars.php" class="function">get_mangled_object_vars()</a></span> や、
     <a href="language.types.array.php#language.types.array.casting" class="link">配列への変換</a>による
     プロパティ内部表現の取得。
    </li>
    <li>
     <strong><code><a href="class.reflectionclass.php#reflectionclass.constants.skip-initialization-on-serialize">ReflectionClass::SKIP_INITIALIZATION_ON_SERIALIZE</a></code></strong>
     が設定された状態での <span class="function"><a href="function.serialize.php" class="function">serialize()</a></span> 。
     ただし <a href="language.oop5.magic.php#object.serialize" class="link">__serialize()</a> または
     <a href="language.oop5.magic.php#object.sleep" class="link">__sleep()</a> が初期化をトリガーしない場合。
    </li>
    <li>
     <span class="methodname"><strong>ReflectionObject::__toString()</strong></span> の呼び出し。
    </li>
    <li>
     <span class="function"><a href="function.var-dump.php" class="function">var_dump()</a></span> または
     <span class="function"><a href="function.debug-zval-dump.php" class="function">debug_zval_dump()</a></span> 。ただし、
     <a href="language.oop5.magic.php#object.debuginfo" class="link">__debugInfo()</a> が初期化をトリガー
     しない場合に限る。
    </li>
   </ul>
  </div>
 </div>

 <div class="sect2" id="language.oop5.lazy-objects.initialization-sequence">
  <h3 class="title">初期化シーケンス</h3>

  <p class="simpara">
   このセクションでは、初期化がトリガーされたときに実行される操作の順序を
   使用する戦略に応じて説明します。
  </p>

  <div class="sect3">
   <h4 class="title">ゴーストオブジェクト</h4>
   <ul class="simplelist">
    <li>
     オブジェクトは非レイジーとしてマークされます。
    </li>
    <li>
     <span class="methodname"><a href="reflectionproperty.skiplazyinitialization.php" class="methodname">ReflectionProperty::skipLazyInitialization()</a></span>または
     <span class="methodname"><a href="reflectionproperty.setrawvaluewithoutlazyinitialization.php" class="methodname">ReflectionProperty::setRawValueWithoutLazyInitialization()</a></span>
     で初期化されていないプロパティは、デフォルト値があれば
     それに設定されます。結果的に、事前に初期化済のプロパティを除き、
     <span class="methodname"><a href="reflectionclass.newinstancewithoutconstructor.php" class="methodname">ReflectionClass::newInstanceWithoutConstructor()</a></span>
     でと似たオブジェクトになります。
    </li>
    <li>
     そのオブジェクトをパラメータとして、イニシャライザ関数が呼び出されます。
     この関数は、オブジェクトの状態を初期化することが
     期待されますが、必須ではありません。<strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong> を返すか、値を返さない必要があります。
     オブジェクトはもはやレイジーではないので、
     関数はプロパティに直接アクセスできます。
    </li>
   </ul>
   <p class="simpara">
    初期化後、オブジェクトはレイジーでない場合と
    区別がつきません。
   </p>
  </div>

  <div class="sect3">
   <h4 class="title">プロキシオブジェクト</h4>
   <ul class="simplelist">
    <li>
     オブジェクトは非レイジーとしてマークされます。
    </li>
    <li>
     ゴーストオブジェクトとは異なり、この段階でオブジェクトのプロパティは
     変更されません。
    </li>
    <li>
     オブジェクトがファクトリ関数に入力されます。
     この関数は、互換性のあるクラスの非レイジーなインスタンスを返す必要があります
     （<span class="methodname"><a href="reflectionclass.newlazyproxy.php" class="methodname">ReflectionClass::newLazyProxy()</a></span>を参照）。
    </li>
    <li>
     返されたインスタンスは <em>実インスタンス</em> として参照され、
     プロキシに接続されます。
    </li>
    <li>
     プロキシのプロパティ値は、
     <span class="function"><a href="function.unset.php" class="function">unset()</a></span> と同等の方法で破棄されます。
    </li>
   </ul>
   <p class="simpara">
    初期化後、プロキシの任意のプロパティへのアクセスは、
    実インスタンスへのアクセスと同じ結果をもたらします。
    宣言済プロパティ、動的プロパティ、存在しないプロパティ、
    <span class="methodname"><a href="reflectionproperty.skiplazyinitialization.php" class="methodname">ReflectionProperty::skipLazyInitialization()</a></span> や
    <span class="methodname"><a href="reflectionproperty.setrawvaluewithoutlazyinitialization.php" class="methodname">ReflectionProperty::setRawValueWithoutLazyInitialization()</a></span> で
    マークされたプロパティを含む、すべてのプロパティへのアクセスは
    実インスタンスに転送されます。
   </p>
   <p class="simpara">
    プロキシオブジェクトが、
    実インスタンスに置き換えられることは<em>ありません</em>。
   </p>
   <p class="simpara">
    ファクトリは最初のパラメータとしてプロキシを受け取りますが、
    それを変更することは期待されていません（変更は許可されますが、
    最終的な初期化ステップ中に失われます）。しかし、プロキシは
    事前に初期化されたプロパティの値、クラス、オブジェクト自体、
    その同一性に基づく決定に使用できます。例えば、イニシャライザは
    実インスタンスを作成する際に初期化されたプロパティの値を利用するかもしれません。
   </p>
  </div>

  <div class="sect3">
   <h4 class="title">共通の動作</h4>

   <p class="simpara">
    イニシャライザまたはファクトリ関数のスコープと<var class="varname">$this</var>の
    コンテキストは変更されず、通常の可視性制約が適用されます。
   </p>

   <p class="simpara">
    初期化が成功した後、イニシャライザまたはファクトリ関数は
    オブジェクトから参照されなくなり、他に参照がなければ
    解放される場合があります。
   </p>

   <p class="simpara">
    イニシャライザが例外をスローした場合、オブジェクトの状態は
    初期化前の状態に戻され、オブジェクトは再びレイジーとマークされます。つまり、
    オブジェクトへの副作用はすべて破棄されます。これは、失敗した場合に
    壊れたインスタンスが生成されてしまうのを防ぎます。ただし、他のオブジェクトへの
    影響など、外部への副作用は元に戻されません。
   </p>
  </div>
 </div>

 <div class="sect2" id="language.oop5.lazy-objects.cloning">
  <h3 class="title">クローン</h3>

  <p class="simpara">
   レイジーオブジェクトを<a href="language.oop5.cloning.php" class="link">クローン</a>すると、
   クローンが作成される前に初期化がトリガーされ、
   結果として初期化されたオブジェクトが得られます。
  </p>

  <p class="simpara">
   プロキシオブジェクトの場合、プロキシとその実インスタンスの両方がクローンされ、
   プロキシのクローンが返されます。
   <a href="language.oop5.cloning.php#object.clone" class="link"><code class="literal">__clone</code></a>メソッドは
   プロキシではなく実インスタンス上で呼び出されます。
   クローンされたプロキシと実インスタンスは
   初期化時にリンクされるため、クローン後のプロキシへのアクセスは
   クローン後の実インスタンスに転送されます。
  </p>

  <p class="simpara">
   この動作により、クローンと元のオブジェクトは独立した状態を持つことが
   保証されます。クローン後に元のオブジェクトまたはそのイニシャライザの状態に
   変更を加えても、クローンには影響しません。実インスタンスのみではなく
   両方をクローンすることで、クローン操作は常に同じクラスのオブジェクトを
   返すことを保証します。
  </p>
 </div>

 <div class="sect2" id="language.oop5.lazy-objects.destructors">
  <h3 class="title">デストラクタ</h3>

  <p class="simpara">
   レイジーゴーストの場合、オブジェクトが初期化されている場合のみ、
   プロキシの場合、実インスタンスが存在する場合のみ、
   デストラクタが呼び出されます。
  </p>

  <p class="simpara">
   <span class="methodname"><a href="reflectionclass.resetaslazyghost.php" class="methodname">ReflectionClass::resetAsLazyGhost()</a></span>および
   <span class="methodname"><a href="reflectionclass.resetaslazyproxy.php" class="methodname">ReflectionClass::resetAsLazyProxy()</a></span>メソッドは、
   リセットされるオブジェクトのデストラクタを呼び出す場合があります。
  </p>
 </div>
</div><?php manual_footer($setup); ?>