<?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.properties.php',
    1 => 'プロパティ',
    2 => 'プロパティ',
  ),
  'up' => 
  array (
    0 => 'language.oop5.php',
    1 => 'クラスとオブジェクト',
  ),
  'prev' => 
  array (
    0 => 'language.oop5.basic.php',
    1 => 'クラスの基礎',
  ),
  'next' => 
  array (
    0 => 'language.oop5.property-hooks.php',
    1 => 'プロパティフック',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ja',
    'path' => 'language/oop5/properties.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.oop5.properties" class="sect1">
  <h2 class="title">プロパティ</h2>

  <p class="para">
   クラスのメンバ変数のことを <em>プロパティ</em> といいます。
   それ以外に <em>フィールド</em>
   などという呼びかたを見たことがあるかもしれません。
   しかし、このマニュアルでは <em>プロパティ</em>
   と呼ぶことにします。
   プロパティは、少なくともひとつのキーワード
   (たとえば <a href="language.oop5.visibility.php" class="link">アクセス権</a>
   のキーワード、
   <a href="language.oop5.static.php" class="link">static キーワード</a>、
   PHP 8.1.0 以降のみ <a href="language.oop5.properties.php#language.oop5.properties.readonly-properties" class="link">readonly</a>) のあとに、
   オプションの型宣言
   (PHP 7.4 以降、但し <code class="code">readonly</code> を除く)
   を続け、
   その後に通常の変数の宣言を続けます。
   宣言時に初期値を設定することもできますが、
   初期値は <a href="language.constants.php" class="link">定数</a> 値でなければなりません。
  </p>
  <blockquote class="note"><p><strong class="note">注意</strong>: 
   <p class="para">
    クラスのプロパティを宣言する代替の方法として、
    <code class="literal">var</code> キーワードを使う方法があります。
   </p>
  </p></blockquote>
  <blockquote class="note"><p><strong class="note">注意</strong>: 
   <span class="simpara">
    <a href="language.oop5.visibility.php" class="link">アクセス権</a>
    を宣言しない場合、プロパティを <code class="literal">public</code>
    として宣言したとみなされます。
   </span>
  </p></blockquote>

  <p class="para">
   クラスのメソッドからstatic でないプロパティにアクセスするには
   <code class="literal">-&gt;</code> (オブジェクト演算子) を使って
   <var class="varname">$this->property</var> のようにします
   (<code class="literal">property</code> のところにプロパティ名を指定します)。
   staticプロパティへのアクセスには <code class="literal">::</code> (ダブルコロン)
   を使って <var class="varname">self::$property</var> のようにします。
   staticプロパティとそうでないプロパティの違いについては、
   <a href="language.oop5.static.php" class="link">static キーワード</a> を参照ください。
  </p>
  <p class="para">
   クラスのメソッドがオブジェクトのコンテキストからコールされたときには、
   擬似変数 <var class="varname">$this</var> が使えます。
   <var class="varname">$this</var> は、呼び出し元のオブジェクトの値です。
  </p>

  <p class="para">
   <div class="example" id="example-1">
    <p><strong>例1 プロパティの宣言</strong></p>
    <div class="example-contents">
<div class="annotation-non-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">SimpleClass<br /></span><span style="color: #007700">{<br />   public </span><span style="color: #0000BB">$var1 </span><span style="color: #007700">= </span><span style="color: #DD0000">'hello ' </span><span style="color: #007700">. </span><span style="color: #DD0000">'world'</span><span style="color: #007700">;<br />   public </span><span style="color: #0000BB">$var2 </span><span style="color: #007700">= &lt;&lt;&lt;EOD<br /></span><span style="color: #DD0000">hello world<br /></span><span style="color: #007700">EOD;<br />   public </span><span style="color: #0000BB">$var3 </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">+</span><span style="color: #0000BB">2</span><span style="color: #007700">;<br />   </span><span style="color: #FF8000">// 無効なプロパティ宣言<br />   </span><span style="color: #007700">public </span><span style="color: #0000BB">$var4 </span><span style="color: #007700">= </span><span style="color: #0000BB">self</span><span style="color: #007700">::</span><span style="color: #0000BB">myStaticMethod</span><span style="color: #007700">();<br />   public </span><span style="color: #0000BB">$var5 </span><span style="color: #007700">= </span><span style="color: #0000BB">$myVar</span><span style="color: #007700">;<br /><br />   </span><span style="color: #FF8000">// 有効なプロパティ宣言<br />   </span><span style="color: #007700">public </span><span style="color: #0000BB">$var6 </span><span style="color: #007700">= </span><span style="color: #0000BB">myConstant</span><span style="color: #007700">;<br />   public </span><span style="color: #0000BB">$var7 </span><span style="color: #007700">= [</span><span style="color: #0000BB">true</span><span style="color: #007700">, </span><span style="color: #0000BB">false</span><span style="color: #007700">];<br /><br />   public </span><span style="color: #0000BB">$var8 </span><span style="color: #007700">= &lt;&lt;&lt;'EOD'<br /></span><span style="color: #DD0000">hello world<br /></span><span style="color: #007700">EOD;<br />   </span><span style="color: #FF8000">// アクセス権を付けない場合<br />   </span><span style="color: #007700">static </span><span style="color: #0000BB">$var9</span><span style="color: #007700">;<br />   readonly </span><span style="color: #0000BB">int $var10</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
    </div>
   
   </div>
  </p>

  <blockquote class="note"><p><strong class="note">注意</strong>: 
   <p class="para">
    クラスやオブジェクトを操作するための便利な関数が用意されています。
    <a href="ref.classobj.php" class="link">クラス/オブジェクト関数</a>
    を参照ください。
   </p>
  </p></blockquote>

  <div class="sect2" id="language.oop5.properties.typed-properties">
   <h3 class="title">型宣言</h3>
  <p class="para">
   PHP 7.4.0 以降は、プロパティの定義に <a href="language.types.declarations.php" class="xref">型宣言</a> を含めることができます。
   但し、<code class="literal">callable</code> 型を除きます。
   <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 /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">User<br /></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 $name</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 $id</span><span style="color: #007700">, ?</span><span style="color: #0000BB">string $name</span><span style="color: #007700">)<br />    {<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 /><br /></span><span style="color: #0000BB">$user </span><span style="color: #007700">= new </span><span style="color: #0000BB">User</span><span style="color: #007700">(</span><span style="color: #0000BB">1234</span><span style="color: #007700">, </span><span style="color: #0000BB">null</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$user</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">id</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$user</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">name</span><span style="color: #007700">);<br /><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>
int(1234)
NULL
</pre></div>
    </div>
   </div>
  </p>

  <p class="para">
    型付きプロパティは、アクセスする前に初期化しなければいけません。
    初期化しないと、<span class="classname"><a href="class.error.php" class="classname">Error</a></span> がスローされます。
    <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 /><br /></span><span style="color: #007700">class </span><span style="color: #0000BB">Shape<br /></span><span style="color: #007700">{<br />    public </span><span style="color: #0000BB">int $numberOfSides</span><span style="color: #007700">;<br />    public </span><span style="color: #0000BB">string $name</span><span style="color: #007700">;<br /><br />    public function </span><span style="color: #0000BB">setNumberOfSides</span><span style="color: #007700">(</span><span style="color: #0000BB">int $numberOfSides</span><span style="color: #007700">): </span><span style="color: #0000BB">void<br />    </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">numberOfSides </span><span style="color: #007700">= </span><span style="color: #0000BB">$numberOfSides</span><span style="color: #007700">;<br />    }<br /><br />    public function </span><span style="color: #0000BB">setName</span><span style="color: #007700">(</span><span style="color: #0000BB">string $name</span><span style="color: #007700">): </span><span style="color: #0000BB">void<br />    </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 function </span><span style="color: #0000BB">getNumberOfSides</span><span style="color: #007700">(): </span><span style="color: #0000BB">int<br />    </span><span style="color: #007700">{<br />        return </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">numberOfSides</span><span style="color: #007700">;<br />    }<br /><br />    public function </span><span style="color: #0000BB">getName</span><span style="color: #007700">(): </span><span style="color: #0000BB">string<br />    </span><span style="color: #007700">{<br />        return </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">name</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$triangle </span><span style="color: #007700">= new </span><span style="color: #0000BB">Shape</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$triangle</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setName</span><span style="color: #007700">(</span><span style="color: #DD0000">"triangle"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">$triangle</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setNumberofSides</span><span style="color: #007700">(</span><span style="color: #0000BB">3</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$triangle</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getName</span><span style="color: #007700">());<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$triangle</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getNumberOfSides</span><span style="color: #007700">());<br /><br /></span><span style="color: #0000BB">$circle </span><span style="color: #007700">= new </span><span style="color: #0000BB">Shape</span><span style="color: #007700">();<br /></span><span style="color: #0000BB">$circle</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setName</span><span style="color: #007700">(</span><span style="color: #DD0000">"circle"</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$circle</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getName</span><span style="color: #007700">());<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$circle</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">getNumberOfSides</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>
string(8) &quot;triangle&quot;
int(3)
string(6) &quot;circle&quot;

Fatal error: Uncaught Error: Typed property Shape::$numberOfSides must not be accessed before initialization
</pre></div>
     </div>
    </div>
   </p>

  </div>

  <div class="sect2" id="language.oop5.properties.readonly-properties">
   <h3 class="title">読み取り専用プロパティ</h3>
   <p class="para">
    PHP 8.1.0 以降では、<code class="code">readonly</code>
    を付けてプロパティを宣言できます。これによって、プロパティを初期化した後に値が変更されることを防止できます。
    PHP 8.4.0 より前のバージョンでは、<code class="literal">readonly</code> プロパティは暗黙的に private-set であり、
    同じクラス内からのみ書き込みが可能でした。
    PHP 8.4.0 以降では、<code class="literal">readonly</code> プロパティは暗黙的に
    <a href="language.oop5.visibility.php#language.oop5.visibility-members-aviz" class="link"><code class="literal">protected(set)</code></a> となり、
    子クラスからも設定可能です。必要に応じて明示的に
    オーバーライドすることもできます。
    <div class="example" id="example-4">
     <p><strong>例4 読み取り専用プロパティの例</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: #007700">class </span><span style="color: #0000BB">Test </span><span style="color: #007700">{<br />   public readonly </span><span style="color: #0000BB">string $prop</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">string $prop</span><span style="color: #007700">) {<br />       </span><span style="color: #FF8000">// 正しい初期化<br />       </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prop </span><span style="color: #007700">= </span><span style="color: #0000BB">$prop</span><span style="color: #007700">;<br />   }<br />}<br /><br /></span><span style="color: #0000BB">$test </span><span style="color: #007700">= new </span><span style="color: #0000BB">Test</span><span style="color: #007700">(</span><span style="color: #DD0000">"foobar"</span><span style="color: #007700">);<br /></span><span style="color: #FF8000">// 正しいプロパティの読み取り<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$test</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prop</span><span style="color: #007700">); </span><span style="color: #FF8000">// string(6) "foobar"<br /><br />// 不正な再代入です。同じ値を代入することは問題ありません。<br /></span><span style="color: #0000BB">$test</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prop </span><span style="color: #007700">= </span><span style="color: #DD0000">"foobar"</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">// Error: Cannot modify readonly property Test::$prop<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
    <blockquote class="note"><p><strong class="note">注意</strong>: 
     <p class="para">
      readonly は、
      <a href="language.oop5.properties.php#language.oop5.properties.typed-properties" class="link">型付きプロパティ</a>
      に対してのみ指定できます。
      型の制約がないプロパティを読み取り専用にしたい場合、
      <a href="language.types.mixed.php" class="xref">Mixed</a> が使えます。
     </p>
    </p></blockquote>
    <blockquote class="note"><p><strong class="note">注意</strong>: 
     <p class="para">
      読み取り専用の static プロパティはサポートされていません。
     </p>
    </p></blockquote>
   </p>
   <p class="para">
    読み取り専用プロパティは、一度しか初期化できません。
    初期化できるのは、
    そのプロパティが宣言された場所と同じスコープに限られます。
    これらのルールから外れたプロパティへの代入や変更を行った場合、
    <span class="classname"><a href="class.error.php" class="classname">Error</a></span> 例外が発生します。
    <div class="example" id="example-5">
     <p><strong>例5 読み取り専用プロパティの不正な初期化</strong></p>
     <div class="example-contents">
<div class="annotation-non-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">Test1 </span><span style="color: #007700">{<br />    public readonly </span><span style="color: #0000BB">string $prop</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">$test1 </span><span style="color: #007700">= new </span><span style="color: #0000BB">Test1</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">// スコープ外からの不正な初期化<br /></span><span style="color: #0000BB">$test1</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prop </span><span style="color: #007700">= </span><span style="color: #DD0000">"foobar"</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">// Error: Cannot initialize readonly property Test1::$prop from global scope<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </p>
   <blockquote class="note"><p><strong class="note">注意</strong>: 
    <p class="para">
     読み取り専用プロパティに対して、
     明示的にデフォルト値を設定することはできません。
     なぜなら、読み取り専用プロパティにデフォルト値を設定することは、
     本質的に定数と同じであり、あまり役に立たないからです。
     <div class="informalexample">
      <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: #007700">class </span><span style="color: #0000BB">Test </span><span style="color: #007700">{<br />    </span><span style="color: #FF8000">// Fatal error: Readonly property Test::$prop cannot have default value<br />    </span><span style="color: #007700">public readonly </span><span style="color: #0000BB">int $prop </span><span style="color: #007700">= </span><span style="color: #0000BB">42</span><span style="color: #007700">;<br />}<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
      </div>

     </div>
    </p>
   </p></blockquote>
   <blockquote class="note"><p><strong class="note">注意</strong>: 
    <p class="para">
     読み取り専用プロパティは、
     一度初期化されると <span class="function"><a href="function.unset.php" class="function">unset()</a></span> できません。
     しかし、初期化する前であれば
     プロパティを宣言した同一のスコープから unset することはできます。
    </p>
   </p></blockquote>
   <p class="para">
    プロパティの変更は、単純な代入にとどまりません。
    次に示すプロパティへの変更例は、
    すべて <span class="classname"><a href="class.error.php" class="classname">Error</a></span> 例外が発生します:
    <div class="informalexample">
     <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: #007700">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 readonly </span><span style="color: #0000BB">int $i </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">,<br />        public readonly array </span><span style="color: #0000BB">$ary </span><span style="color: #007700">= [],<br />    ) {}<br />}<br /><br /></span><span style="color: #0000BB">$test </span><span style="color: #007700">= new </span><span style="color: #0000BB">Test</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$test</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">i </span><span style="color: #007700">+= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$test</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">i</span><span style="color: #007700">++;<br />++</span><span style="color: #0000BB">$test</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">i</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$test</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">ary</span><span style="color: #007700">[] = </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$test</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">ary</span><span style="color: #007700">[</span><span style="color: #0000BB">0</span><span style="color: #007700">][] = </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br />unset(</span><span style="color: #0000BB">$test</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">ary</span><span style="color: #007700">[</span><span style="color: #0000BB">0</span><span style="color: #007700">]);<br /></span><span style="color: #0000BB">$ref </span><span style="color: #007700">=&amp; </span><span style="color: #0000BB">$test</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">i</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$test</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">i </span><span style="color: #007700">=&amp; </span><span style="color: #0000BB">$ref</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">byRef</span><span style="color: #007700">(</span><span style="color: #0000BB">$test</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">i</span><span style="color: #007700">);<br />foreach (</span><span style="color: #0000BB">$test </span><span style="color: #007700">as &amp;</span><span style="color: #0000BB">$prop</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </p>
   <p class="para">
    但し、プロパティが読み取り専用であっても、
    そのプロパティの内部まで変更できなくなるわけではありません。
    読み取り専用プロパティ内部のオブジェクト(またはリソース) は、
    内部的に変更しても構いません:
    <div class="informalexample">
     <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: #007700">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">(public readonly </span><span style="color: #0000BB">object $obj</span><span style="color: #007700">) {}<br />}<br /><br /></span><span style="color: #0000BB">$test </span><span style="color: #007700">= new </span><span style="color: #0000BB">Test</span><span style="color: #007700">(new </span><span style="color: #0000BB">stdClass</span><span style="color: #007700">);<br /></span><span style="color: #FF8000">// 有効なオブジェクト内部の変更<br /></span><span style="color: #0000BB">$test</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">obj</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">foo </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">// 不正な再代入<br /></span><span style="color: #0000BB">$test</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">obj </span><span style="color: #007700">= new </span><span style="color: #0000BB">stdClass</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </p>
   <p class="para">
    PHP 8.3.0 以降では、
    読み取り専用プロパティは <a href="language.oop5.cloning.php#object.clone" class="link">__clone()</a> を使ったオブジェクトのクローン時に再初期化できるようになりました。
    <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 /></span><span style="color: #007700">class </span><span style="color: #0000BB">Test1 </span><span style="color: #007700">{<br />    public readonly ?</span><span style="color: #0000BB">string $prop</span><span style="color: #007700">;<br /><br />    public function </span><span style="color: #0000BB">__clone</span><span style="color: #007700">() {<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prop </span><span style="color: #007700">= </span><span style="color: #0000BB">null</span><span style="color: #007700">;<br />    }<br /><br />    public function </span><span style="color: #0000BB">setProp</span><span style="color: #007700">(</span><span style="color: #0000BB">string $prop</span><span style="color: #007700">): </span><span style="color: #0000BB">void </span><span style="color: #007700">{<br />        </span><span style="color: #0000BB">$this</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prop </span><span style="color: #007700">= </span><span style="color: #0000BB">$prop</span><span style="color: #007700">;<br />    }<br />}<br /><br /></span><span style="color: #0000BB">$test1 </span><span style="color: #007700">= new </span><span style="color: #0000BB">Test1</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$test1</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">setProp</span><span style="color: #007700">(</span><span style="color: #DD0000">'foobar'</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">$test2 </span><span style="color: #007700">= clone </span><span style="color: #0000BB">$test1</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$test2</span><span style="color: #007700">-&gt;</span><span style="color: #0000BB">prop</span><span style="color: #007700">); </span><span style="color: #FF8000">// NULL<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
   </p>
  </div>

  <div class="sect2" id="language.oop5.properties.dynamic-properties">
   <h3 class="title">動的なプロパティ</h3>
   <p class="para">
    オブジェクトに対して、存在しないプロパティを代入しようとした場合、
    PHP は自動的に対応するプロパティを作成します。
    こうして作成された動的なプロパティは、
    そのインスタンスで <em>のみ</em> 使えます。
   </p>

   <div class="warning"><strong class="warning">警告</strong>
    <p class="simpara">
     動的なプロパティは、PHP 8.2.0 以降は推奨されなくなりました。
     代わりに、プロパティを宣言することを推奨します。
     任意のプロパティの名前を扱うには、
     クラスがマジックメソッド
     <a href="language.oop5.overloading.php#object.get" class="link">__get()</a> と
     <a href="language.oop5.overloading.php#object.set" class="link">__set()</a> を実装すべきです。
     動的なプロパティを使うための最終手段として、
     アトリビュート <code class="code">#[\AllowDynamicProperties]</code>
     でクラスをマークすることができます。
    </p>
   </div>
  </div>

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