<?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.decon.php',
    1 => 'コンストラクタとデストラクタ',
    2 => 'コンストラクタとデストラクタ',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'クラスとオブジェクト',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.autoload.php',
    1 => 'クラスのオートローディング',
  ),
  'next' => 
  array (
    0 => 'language.oop5.visibility.php',
    1 => 'アクセス権',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ja',
    'path' => 'language/oop5/decon.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.oop5.decon" class="sect1">
 <h2 class="title">コンストラクタとデストラクタ</h2>

 <div class="sect2" id="language.oop5.decon.constructor">
  <h3 class="title">コンストラクタ</h3>
   <div class="methodsynopsis dc-description" id="object.construct">
    <span class="methodname"><strong>__construct</strong></span>(<span class="methodparam"><span class="type"><a href="language.types.mixed.php" class="type mixed">mixed</a></span> <code class="parameter">...$values</code><span class="initializer"> = &quot;&quot;</span></span>): <span class="type"><a href="language.types.void.php" class="type void">void</a></span></div>

  <p class="para">
   PHP では、開発者がクラスのコンストラクタメソッドを宣言することが
   できます。コンストラクタメソッドを有するクラスは、新たにオブジェクトが
   生成される度にこのメソッドをコールします。これにより、
   そのオブジェクトを使用する前に必要な初期化を行うことができます。
  </p>
  <blockquote class="note"><p><strong class="note">注意</strong>: 
   <span class="simpara">
    子クラスがコンストラクタを有している場合、親クラスのコンストラクタが
    暗黙の内にコールされることはありません。
    親クラスのコンストラクタを実行するには、子クラスのコンストラクタの
    中で <span class="function"><strong>parent::__construct()</strong></span> をコールすることが
    必要です。
    子クラスでコンストラクタを定義していない場合は、親クラスのコンストラクタを継承します
    (ただし、private 宣言されている場合は除く)。
    これは、通常のクラスメソッドと同様です。
   </span>
  </p></blockquote>
  <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">BaseClass </span><span style="color: #007700">{<br />    function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">() {<br />        print </span><span style="color: #DD0000">"In BaseClass constructor\n"</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">SubClass </span><span style="color: #007700">extends </span><span style="color: #0000BB">BaseClass </span><span style="color: #007700">{<br />    function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">() {<br />        </span><span style="color: #0000BB">parent</span><span style="color: #007700">::</span><span style="color: #0000BB">__construct</span><span style="color: #007700">();<br />        print </span><span style="color: #DD0000">"In SubClass constructor\n"</span><span style="color: #007700">;<br />    }<br />}<br /><br />class </span><span style="color: #0000BB">OtherSubClass </span><span style="color: #007700">extends </span><span style="color: #0000BB">BaseClass </span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// BaseClass のコンストラクタを継承します<br /></span><span style="color: #007700">}<br /><br /></span><span style="color: #FF8000">// In BaseClass constructor<br /></span><span style="color: #0000BB">$obj </span><span style="color: #007700">= new </span><span style="color: #0000BB">BaseClass</span><span style="color: #007700">();<br /><br /></span><span style="color: #FF8000">// In BaseClass constructor<br />// In SubClass constructor<br /></span><span style="color: #0000BB">$obj </span><span style="color: #007700">= new </span><span style="color: #0000BB">SubClass</span><span style="color: #007700">();<br /><br /></span><span style="color: #FF8000">// In BaseClass constructor<br /></span><span style="color: #0000BB">$obj </span><span style="color: #007700">= new </span><span style="color: #0000BB">OtherSubClass</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
   <p class="para">
    他のメソッドと異なり、<a href="language.oop5.decon.php#object.construct" class="link">__construct()</a>
    を子クラスでオーバライドしても、
    <a href="language.oop5.basic.php#language.oop.lsp" class="link">シグネチャの互換性に関するルール</a> は適用されません。
   </p>
   <p class="para">
    コンストラクタは、対応するオブジェクトを初期化する間に呼び出されるメソッドです。
    よって、任意の数の引数を取ることが出来ます。
    この引数は必須にすることもできますし、型宣言もできますし、デフォルト値を取ったりすることもできます。
    コンストラクタの引数は、クラス名の後の括弧に、引数を置くことで指定することが出来ます。
   </p>
   <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">Point </span><span style="color: #007700">{<br />    protected </span><span style="color: #0000BB">int $x</span><span style="color: #007700">;<br />    protected </span><span style="color: #0000BB">int $y</span><span style="color: #007700">;<br /><br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">(</span><span style="color: #0000BB">int $x</span><span style="color: #007700">, </span><span style="color: #0000BB">int $y </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">) {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">x </span><span style="color: #007700">= </span><span style="color: #0000BB">$x</span><span style="color: #007700">;<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">y </span><span style="color: #007700">= </span><span style="color: #0000BB">$y</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #FF8000">// 引数を両方渡す<br /></span><span style="color: #0000BB">$p1 </span><span style="color: #007700">= new </span><span style="color: #0000BB">Point</span><span style="color: #007700">(</span><span style="color: #0000BB">4</span><span style="color: #007700">, </span><span style="color: #0000BB">5</span><span style="color: #007700">);<br /></span><span style="color: #FF8000">// 必須の引数のみを渡す。$y はデフォルト値0になります。<br /></span><span style="color: #0000BB">$p2 </span><span style="color: #007700">= new </span><span style="color: #0000BB">Point</span><span style="color: #007700">(</span><span style="color: #0000BB">4</span><span style="color: #007700">);<br /></span><span style="color: #FF8000">// 名前付き引数(PHP 8.0 以降):<br /></span><span style="color: #0000BB">$p3 </span><span style="color: #007700">= new </span><span style="color: #0000BB">Point</span><span style="color: #007700">(</span><span style="color: #0000BB">y</span><span style="color: #007700">: </span><span style="color: #0000BB">5</span><span style="color: #007700">, </span><span style="color: #0000BB">x</span><span style="color: #007700">: </span><span style="color: #0000BB">4</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>

   </div>
   <p class="para">
    クラスにコンストラクタが存在しない場合、あるいは、コンストラクタに必須の引数がない場合、
    括弧は省略できます。
   </p>
   <div class="sect3">
    <h4 class="title">古いスタイルのコンストラクタ</h4>
    <p class="para">
     PHP 8.0.0 より前のバージョンでは、グローバル名前空間にあるクラスは、
     クラス名と同じ名前のメソッドが古いスタイルのコンストラクタとして解釈されます。
     この文法は推奨されておらず、<strong><code><a href="errorfunc.constants.php#constant.e-deprecated">E_DEPRECATED</a></code></strong> が発生するものの、
     まだこの関数をコンストラクタとして呼び出すことが出来ます。
     <a href="language.oop5.decon.php#object.construct" class="link">__construct()</a>
     とクラス名と同じ名前のメソッドが両方定義されていた場合は、
     <a href="language.oop5.decon.php#object.construct" class="link">__construct()</a> がコンストラクタとして呼び出されます。
    </p>
    <p class="para">
     名前空間の中に存在するクラスについては、
     PHP 8.0.0 以降では、
     クラス名と同じ名前のメソッドはなんの意味も持ちません。
    </p>
    <p class="para">新しいコードでは、常に <a href="language.oop5.decon.php#object.construct" class="link">__construct()</a> を使うようにしましょう。
    </p>
   </div>
   <div class="sect3" id="language.oop5.decon.constructor.promotion">
    <h4 class="title">コンストラクタのプロモーション</h4>
    <p class="para">
     PHP 8.0.0 以降では、コンストラクタのパラメータを
     対応するオブジェクトのプロパティに昇格させることができます。
     コンストラクタのパラメータをプロパティに代入し、それ以外の操作を行わないことはよくあることです。
     コンストラクタのプロモーションは、こういった場合の短縮記法を提供します。
     「コンストラクタを引数と一緒に使う」の例は、次のように書き直すことが出来ます。
    </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">Point </span><span style="color: #007700">{<br />    public function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">(protected </span><span style="color: #0000BB">int $x</span><span style="color: #007700">, protected </span><span style="color: #0000BB">int $y </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">) {<br />    }<br />}</span></span></code></div>
     </div>

    </div>
    <p class="para">
     コンストラクタの引数に修飾子が含まれている場合、
     PHP はそれをオブジェクトのプロパティ、かつコンストラクタの引数であると解釈します。
     そして、その引数の値をプロパティに代入します。
     コンストラクタの本体は空にすることもできますし、
     他の文を含めることも出来ます。
     引数の値が対応するプロパティに代入された後、
     追加の文が実行されます。
    </p>
    <p class="para">
     全ての引数をプロパティに昇格させる必要はありません。
     昇格させる引数と、させない引数を混ぜることもできます。
     プロパティに昇格した引数は、コンストラクタの呼び出しコードになんの影響も与えません。
    </p>
    <blockquote class="note"><p><strong class="note">注意</strong>: 
     <p class="para">
      <a href="language.oop5.visibility.php" class="link">アクセス権</a>
      の修飾子 (<code class="literal">public</code>,
      <code class="literal">protected</code>, <code class="literal">private</code>)
      を使うことが、プロパティの昇格を行わせるもっとも適したやり方ですが、
      他にも (<code class="literal">readonly</code> のような) 単一の修飾子を使っても、
      同じ昇格の効果が得られます。
     </p>
    </p></blockquote>
    <blockquote class="note"><p><strong class="note">注意</strong>: 
     <p class="para">
      PHP のエンジンが曖昧になってしまうため、
      オブジェクトのプロパティは、<span class="type"><a href="language.types.callable.php" class="type callable">callable</a></span> 型にすることは出来ません。
      そのため、昇格させる引数も <span class="type"><a href="language.types.callable.php" class="type callable">callable</a></span> 型にはできません。
      しかし、それ以外の
      <a href="language.types.declarations.php" class="link">型宣言</a> は許されています。
     </p>
    </p></blockquote>
    <blockquote class="note"><p><strong class="note">注意</strong>: 
     <p class="para">
      コンストラクタで昇格したプロパティはプロパティと関数のパラメータ両方に戻されるので、プロパティとパラメータの両方に対するあらゆる命名規則が適用されます。
     </p>
    </p></blockquote>
    <blockquote class="note"><p><strong class="note">注意</strong>: 
     <p class="para">
      昇格したコンストラクタの引数に指定された
      <a href="language.attributes.php" class="link">アトリビュート</a> は、
      プロパティと引数の両方にコピーされます。
      昇格したコンストラクタの引数に指定されたデフォルト値は、
      引数にだけコピーされます。プロパティにはコピーされません。
     </p>
    </p></blockquote>
   </div>

   <div class="sect3" id="language.oop5.decon.constructor.new">
    <h4 class="title">初期化時の new キーワード</h4>
    <p class="para">
     PHP 8.1.0 以降では、
     パラメータのデフォルト値の初期化時、
     static 変数の初期化時、
     グローバルな定数の初期化時に、
     new を指定したオブジェクトが使えます。
     同じものを、アトリビュートの引数や
     <span class="function"><a href="function.define.php" class="function">define()</a></span> に渡せるようにもなっています。
    </p>
    <blockquote class="note"><p><strong class="note">注意</strong>: 
     <p class="para">
      この文脈で、動的なクラス名、文字列でないクラス名、
      無名クラスを指定することはできません。
      また、配列で引数を展開させることはできません。
      未サポートの式を引数に指定することもできません。
     </p>
    </p></blockquote>
    <div class="example" id="example-4">
     <p><strong>例4 初期化時に new キーワードを使う</strong></p>
     <div class="example-contents">
<div class="annotation-non-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #FF8000">// 以下は全て許可されます<br /></span><span style="color: #007700">static </span><span style="color: #0000BB">$x </span><span style="color: #007700">= new </span><span style="color: #0000BB">Foo</span><span style="color: #007700">;<br /><br />const </span><span style="color: #0000BB">C </span><span style="color: #007700">= new </span><span style="color: #0000BB">Foo</span><span style="color: #007700">;<br /> <br />function </span><span style="color: #0000BB">test</span><span style="color: #007700">(</span><span style="color: #0000BB">$param </span><span style="color: #007700">= new </span><span style="color: #0000BB">Foo</span><span style="color: #007700">) {}<br /> <br />#[</span><span style="color: #0000BB">AnAttribute</span><span style="color: #007700">(new </span><span style="color: #0000BB">Foo</span><span style="color: #007700">)]<br />class </span><span style="color: #0000BB">Test </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">$prop </span><span style="color: #007700">= new </span><span style="color: #0000BB">Foo</span><span style="color: #007700">,<br />    ) {}<br />}<br /><br /></span><span style="color: #FF8000">// 以下はいずれも許されません(コンパイルエラーになります)<br /></span><span style="color: #007700">function </span><span style="color: #0000BB">test</span><span style="color: #007700">(<br />    </span><span style="color: #0000BB">$a </span><span style="color: #007700">= new (</span><span style="color: #0000BB">CLASS_NAME_CONSTANT</span><span style="color: #007700">)(), </span><span style="color: #FF8000">// 動的なクラス名<br />    </span><span style="color: #0000BB">$b </span><span style="color: #007700">= new class {}, </span><span style="color: #FF8000">// 無名クラス<br />    </span><span style="color: #0000BB">$c </span><span style="color: #007700">= new </span><span style="color: #0000BB">A</span><span style="color: #007700">(...[]), </span><span style="color: #FF8000">// 引数の展開<br />    </span><span style="color: #0000BB">$d </span><span style="color: #007700">= new </span><span style="color: #0000BB">B</span><span style="color: #007700">(</span><span style="color: #0000BB">$abc</span><span style="color: #007700">), </span><span style="color: #FF8000">// 定数式の展開はサポートされていません<br /></span><span style="color: #007700">) {}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </div>
   
   <div class="sect3" id="language.oop5.decon.constructor.static">
    <h4 class="title">static な生成メソッド</h4>
    <p class="para">
     PHP は、クラスひとつにつき、コンストラクタをひとつだけサポートしています。
     しかし、場合によっては異なる入力を使い、
     異なるやり方でオブジェクトを生成させるのが望ましい場合もあります。
     その場合におすすめなのが、staticメソッドをコンストラクタのラッパーとして使うことです。
    </p>
    <div class="example" id="example-5">
     <p><strong>例5 static な生成メソッドを使う</strong></p>
     <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$some_json_string </span><span style="color: #007700">= </span><span style="color: #DD0000">'{ "id": 1004, "name": "Elephpant" }'</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$some_xml_string </span><span style="color: #007700">= </span><span style="color: #DD0000">"&lt;animal&gt;&lt;id&gt;1005&lt;/id&gt;&lt;name&gt;Elephpant&lt;/name&gt;&lt;/animal&gt;"</span><span style="color: #007700">;<br /><br />class </span><span style="color: #0000BB">Product </span><span style="color: #007700">{<br /><br />    private ?</span><span style="color: #0000BB">int $id</span><span style="color: #007700">;<br />    private ?</span><span style="color: #0000BB">string $name</span><span style="color: #007700">;<br /><br />    private function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">(?</span><span style="color: #0000BB">int $id </span><span style="color: #007700">= </span><span style="color: #0000BB">null</span><span style="color: #007700">, ?</span><span style="color: #0000BB">string $name </span><span style="color: #007700">= </span><span style="color: #0000BB">null</span><span style="color: #007700">) {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">id </span><span style="color: #007700">= </span><span style="color: #0000BB">$id</span><span style="color: #007700">;<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">name </span><span style="color: #007700">= </span><span style="color: #0000BB">$name</span><span style="color: #007700">;<br />    }<br /><br />    public static function </span><span style="color: #0000BB">fromBasicData</span><span style="color: #007700">(</span><span style="color: #0000BB">int $id</span><span style="color: #007700">, </span><span style="color: #0000BB">string $name</span><span style="color: #007700">): static {<br />        </span><span style="color: #0000BB">$new </span><span style="color: #007700">= new static(</span><span style="color: #0000BB">$id</span><span style="color: #007700">, </span><span style="color: #0000BB">$name</span><span style="color: #007700">);<br />        return </span><span style="color: #0000BB">$new</span><span style="color: #007700">;<br />    }<br /><br />    public static function </span><span style="color: #0000BB">fromJson</span><span style="color: #007700">(</span><span style="color: #0000BB">string $json</span><span style="color: #007700">): static {<br />        </span><span style="color: #0000BB">$data </span><span style="color: #007700">= </span><span style="color: #0000BB">json_decode</span><span style="color: #007700">(</span><span style="color: #0000BB">$json</span><span style="color: #007700">, </span><span style="color: #0000BB">true</span><span style="color: #007700">);<br />        return new static(</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">'name'</span><span style="color: #007700">]);<br />    }<br /><br />    public static function </span><span style="color: #0000BB">fromXml</span><span style="color: #007700">(</span><span style="color: #0000BB">string $xml</span><span style="color: #007700">): static {<br />        </span><span style="color: #0000BB">$data </span><span style="color: #007700">= </span><span style="color: #0000BB">simplexml_load_string</span><span style="color: #007700">(</span><span style="color: #0000BB">$xml</span><span style="color: #007700">);<br />        </span><span style="color: #0000BB">$new </span><span style="color: #007700">= new static();<br />        </span><span style="color: #0000BB">$new</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">id </span><span style="color: #007700">= (int) </span><span style="color: #0000BB">$data</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">id</span><span style="color: #007700">;<br />        </span><span style="color: #0000BB">$new</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">name </span><span style="color: #007700">= </span><span style="color: #0000BB">$data</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">name</span><span style="color: #007700">;<br />        return </span><span style="color: #0000BB">$new</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$p1 </span><span style="color: #007700">= </span><span style="color: #0000BB">Product</span><span style="color: #007700">::</span><span style="color: #0000BB">fromBasicData</span><span style="color: #007700">(</span><span style="color: #0000BB">5</span><span style="color: #007700">, </span><span style="color: #DD0000">'Widget'</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$p2 </span><span style="color: #007700">= </span><span style="color: #0000BB">Product</span><span style="color: #007700">::</span><span style="color: #0000BB">fromJson</span><span style="color: #007700">(</span><span style="color: #0000BB">$some_json_string</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$p3 </span><span style="color: #007700">= </span><span style="color: #0000BB">Product</span><span style="color: #007700">::</span><span style="color: #0000BB">fromXml</span><span style="color: #007700">(</span><span style="color: #0000BB">$some_xml_string</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$p1</span><span style="color: #007700">, </span><span style="color: #0000BB">$p2</span><span style="color: #007700">, </span><span style="color: #0000BB">$p3</span><span style="color: #007700">);</span></span></code></div>
     </div>

    </div>
    <p class="para">
     コンストラクタは外部から呼ばれることを防ぐため、private または protected にしておきます。
     この場合、staticメソッドだけがクラスをインスタンス化するのに使えます。
     なぜなら、staticメソッドは、同じオブジェクトのインスタンスでなくとも、
     private なメソッドにアクセスできる同じクラスのメソッド定義として存在するからです。
     コンストラクタを private にすることはオプションです。使い方によっては意味がないかもしれません...
    </p>
    <p class="para">
     上の public なstaticメソッドは、オブジェクトをインスタンス化する3つの異なるやり方を示しています。
    </p>
    <ul class="simplelist">
     <li><code class="code">fromBasicData()</code> は、必要となる必須のパラメータを取り、
     コンストラクタを呼ぶことでオブジェクトを生成し、その結果を返します。</li>
     <li><code class="code">fromJson()</code> は、JSON文字列を受け取り、
     コンストラクタで必要なフォーマットに変換するための前処理を行います。
     その上で、新しいオブジェクトを返します。</li>
     <li><code class="code">fromXml()</code> は、XML文字列を受け取り、前処理をします。
     そして生のオブジェクトを生成します。コンストラクタは呼び出されていますが、
     全てのパラメータはオプションなので、その実行はスキップされます。
     結果を返す前に、オブジェクトのプロパティに直接値を代入しています。</li>
    </ul>
    <p class="para">
     上の3つの場合全てで、<code class="code">static</code> キーワードはコードが存在するクラスの名前として解釈されます。
     この場合は <code class="code">Product</code> です。
    </p>
   </div>
  </div>

 <div class="sect2" id="language.oop5.decon.destructor">
  <h3 class="title">デストラクタ</h3>
   <div class="methodsynopsis dc-description" id="object.destruct">
   <span class="methodname"><strong>__destruct</strong></span>(): <span class="type"><a href="language.types.void.php" class="type void">void</a></span></div>

  <p class="para">
   PHP には、C++ のような他のオブジェクト指向言語に似たデストラクタの概念があります。
   デストラクタメソッドは、
   特定のオブジェクトを参照するリファレンスがひとつもなくなったときにコールされます。
   あるいは、スクリプトの終了時にも順不同でコールされます。
  </p>
  <div class="example" id="example-6">
   <p><strong>例6 デストラクタの例</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">MyDestructableClass <br /></span><span style="color: #007700">{<br />    function </span><span style="color: #0000BB">__construct</span><span style="color: #007700">() {<br />        print </span><span style="color: #DD0000">"In constructor\n"</span><span style="color: #007700">;<br />    }<br /><br />    function </span><span style="color: #0000BB">__destruct</span><span style="color: #007700">() {<br />        print </span><span style="color: #DD0000">"Destroying " </span><span style="color: #007700">. </span><span style="color: #0000BB">__CLASS__ </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">$obj </span><span style="color: #007700">= new </span><span style="color: #0000BB">MyDestructableClass</span><span style="color: #007700">();</span></span></code></div>
   </div>

  </div>
  <p class="para">
   コンストラクタと同様、親クラスのデストラクタがエンジンにより暗黙のうちに
   コールされるということはありません。親クラスのデストラクタを実行するには、
   デストラクタの中で明示的に <span class="function"><strong>parent::__destruct()</strong></span>
   をコールする必要があります。
   また、コンストラクタと同様、子クラスでデストラクタを定義していない場合は
   親クラスのデストラクタを継承します。
  </p>
   <p class="para">
    <span class="function"><a href="function.exit.php" class="function">exit()</a></span>
    でスクリプトの実行を止めた場合にもデストラクタはコールされます。
    デストラクタの内部で <span class="function"><a href="function.exit.php" class="function">exit()</a></span> をコールすると、
    それ以降のシャットダウンルーチンを実行しません。
   </p>
   <blockquote class="note"><p><strong class="note">注意</strong>: 
    <p class="para">
     スクリプトのシャットダウン時にデストラクタがコールされた場合は、
     HTTP ヘッダはすでに送信されています。スクリプトのシャットダウン時の作業ディレクトリは、
     SAPI によっては (たとえば Apache など) 異なります。
    </p>
    <p class="para">
     デストラクタが自身のオブジェクトへの新しい参照を作成した場合、参照カウントが再びゼロになったときや
     シャットダウンシーケンス中に、再度呼び出されることはありません。
    </p>
    <p class="para">
     PHP 8.4.0 以降、 <a href="features.gc.collecting-cycles.php" class="link">ガベージサイクルの収集</a> が
     <a href="language.fibers.php" class="link">ファイバー</a>の実行中に発生した場合、
     回収がスケジュールされたオブジェクトのデストラクタは、 <code class="literal">gc_destructor_fiber</code>と呼ばれる
     別のファイバー内で実行されます。
     このファイバーが中断された場合、残りのデストラクタを実行するために新しいファイバーが作成されます。
     中断された <code class="literal">gc_destructor_fiber</code> はガベージコレクタによって参照されなくなり、
     他の参照がなければ回収される可能性があります。
     デストラクタが中断されたオブジェクトは、デストラクタが復帰するかファイバー自体が回収されるまで回収されません。
    </p>
   </p></blockquote>
   <blockquote class="note"><p><strong class="note">注意</strong>: 
    <p class="para">
     デストラクタの中から (スクリプトの終了処理時に)
     例外をスローしようとすると、致命的なエラーを引き起こします。
    </p>
   </p></blockquote>
 </div>

</div><?php manual_footer($setup); ?>