<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/language.operators.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ja',
  ),
  'this' => 
  array (
    0 => 'language.operators.precedence.php',
    1 => '演算子の優先順位',
    2 => '演算子の優先順位',
  ),
  'up' => 
  array (
    0 => 'language.operators.php',
    1 => '演算子',
  ),
  'prev' => 
  array (
    0 => 'language.operators.php',
    1 => '演算子',
  ),
  'next' => 
  array (
    0 => 'language.operators.arithmetic.php',
    1 => '算術演算子',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ja',
    'path' => 'language/operators/precedence.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="language.operators.precedence" class="sect1">
 <h2 class="title">演算子の優先順位</h2>
 
 <p class="para">
  演算子の優先順位は、二つの式が&quot;緊密に&quot;結合している度合いを指定します。
  例えば、式 <code class="literal">1 + 5 * 3</code> の答えは
  <code class="literal">16</code> になり、<code class="literal">18</code> とはなりません。
  これは乗算演算子(&quot;*&quot;)は、加算演算子(&quot;+&quot;)より高い優先順位を有するか
  らです。必要に応じて強制的に優先順位を設定するために括弧を使用する
  ことが可能です。例えば、<code class="literal">18</code>と評価するためには、
  <code class="literal">(1 + 5) * 3</code> とします。
 </p>
 <p class="para">
  演算子の優先順位が等しい場合は、その結合性によって評価順
  (右から評価するのか、あるいは左から評価するのか) が決まります。
  たとえば &quot;-&quot; は左結合なので、
  <code class="literal">1 - 2 - 3</code> は <code class="literal">(1 - 2) - 3</code> とグループ分けされて、
  評価結果は <code class="literal">-4</code> になります。
  一方、&quot;=&quot; は右結合です。つまり <code class="literal">$a = $b = $c</code> のグループ分けは
  <code class="literal">$a = ($b = $c)</code> となります。
 </p>
 <p class="para">
  優先順位が同じで結合しない演算子を並べることはできません。つまり、たとえば
  <code class="literal">1 &lt; 2 &gt; 1</code> は PHP では無効になります。
  一方 <code class="literal">1 &lt;= 1 == 1</code> は問題ありません。
  <code class="literal">==</code> 演算子の優先順位が
  <code class="literal">&lt;=</code> 演算子より低いからです。
 </p>
 <p class="para">
  演算子の結合は、
  二項演算子(および三項演算子) の場合にだけ意味があります。
  単項演算子は、前置または後置しかないため、
  演算子の結合の考え方は適用できません。
  たとえば、
  <code class="literal">!!$a</code> は、
  <code class="literal">!(!$a)</code> という形でのみグループ化できます。
 </p>
 <p class="para">
  厳密には不要な場所であっても、括弧をつけておけばコードの可読性があがります。
  明示的にグループ分けをしておくことで、演算子の優先順位や結合性による暗黙のグループ分けに頼らずに済むからです。
 </p>
 <p class="para">
  次の表では、優先順位が高い順に演算子を挙げています。
  同じ行にある演算子は優先順位が等しくなります。そのような場合は、
  結合時の評価にしたがってグループ分けが決まります。
  <table class="doctable table">
   <caption><strong>演算子の優先順位</strong></caption>
   
    <thead>
     <tr>
      <th>結合時の評価</th>
      <th>演算子</th>
      <th>追加情報</th>
     </tr>

    </thead>

    <tbody class="tbody">
     <tr>
      <td>(n/a)</td>
      <td>
       <code class="literal">clone</code>
       <code class="literal">new</code>
      </td>
      <td><a href="language.oop5.cloning.php" class="link">clone</a> および <a href="language.oop5.basic.php#language.oop5.basic.new" class="link">new</a></td>
     </tr>

     <tr>
      <td>right</td>
      <td><code class="literal">**</code></td>
      <td><a href="language.operators.arithmetic.php" class="link">算術演算子</a></td>
     </tr>

     <tr>
      <td>(n/a)</td>
      <td>
       <code class="literal">+</code> 
       <code class="literal">-</code> 
       <code class="literal">++</code> 
       <code class="literal">--</code> 
       <code class="literal">~</code> 
       <code class="literal">(int)</code> 
       <code class="literal">(float)</code> 
       <code class="literal">(string)</code> 
       <code class="literal">(array)</code>
       <code class="literal">(object)</code> 
       <code class="literal">(bool)</code> 
       <code class="literal">@</code>
      </td>
      <td>
       <a href="language.operators.arithmetic.php" class="link">算術演算子</a> (単項演算の <code class="literal">+</code> と <code class="literal">-</code>),
       <a href="language.operators.increment.php" class="link">加算子/減算子</a>,
       <a href="language.operators.bitwise.php" class="link">ビット演算子</a>,
       <a href="language.types.type-juggling.php#language.types.typecasting" class="link">型の相互変換</a> そして
       <a href="language.operators.errorcontrol.php" class="link">エラー制御演算子</a>
      </td>
     </tr>

     <tr>
      <td>left</td>
      <td><code class="literal">instanceof</code></td>
      <td>
       <a href="language.operators.type.php" class="link">型演算子</a>
      </td>
     </tr>

     <tr>
      <td>(n/a)</td>
      <td><code class="literal">!</code></td>
      <td>
       <a href="language.operators.logical.php" class="link">論理演算子</a>
      </td>
     </tr>

     <tr>
      <td>left</td>
      <td>
       <code class="literal">*</code>
       <code class="literal">/</code>
       <code class="literal">%</code>
      </td>
      <td>
       <a href="language.operators.arithmetic.php" class="link">算術演算子</a>
      </td>
     </tr>

     <tr>
      <td>left</td>
      <td>
       <code class="literal">+</code> 
       <code class="literal">-</code> 
       <code class="literal">.</code>
      </td>
      <td>
       <a href="language.operators.arithmetic.php" class="link">算術演算子</a> (二項演算の <code class="literal">+</code> と <code class="literal">-</code>),
       <a href="language.operators.array.php" class="link">配列演算子</a> そして
       <a href="language.operators.string.php" class="link">文字列演算子</a> (PHP 8.0.0 より前のバージョンの<code class="literal">.</code>)
      </td>
     </tr>

     <tr>
      <td>left</td>
      <td>
       <code class="literal">&lt;&lt;</code> 
       <code class="literal">&gt;&gt;</code>
      </td>
      <td>
       <a href="language.operators.bitwise.php" class="link">ビット演算子</a>
      </td>
     </tr>

     <tr>
      <td>left</td>
      <td><code class="literal">.</code></td>
      <td>
       <a href="language.operators.string.php" class="link">文字列演算子</a> (PHP 8.0.0 以降)
      </td>
     </tr>

     <tr>
      <td>left</td>
      <td><code class="literal">|&gt;</code></td>
      <td>
       <a href="language.operators.functional.php" class="link">パイプ演算子</a>
      </td>
     </tr>

     <tr>
      <td>結合しない</td>
      <td>
       <code class="literal">&lt;</code> 
       <code class="literal">&lt;=</code> 
       <code class="literal">&gt;</code> 
       <code class="literal">&gt;=</code>
      </td>
      <td>
       <a href="language.operators.comparison.php" class="link">比較演算子</a>
      </td>
     </tr>

     <tr>
      <td>結合しない</td>
      <td>
       <code class="literal">==</code>
       <code class="literal">!=</code> 
       <code class="literal">===</code> 
       <code class="literal">!==</code> 
       <code class="literal">&lt;&gt;</code>
       <code class="literal">&lt;=&gt;</code>
      </td>
      <td>
       <a href="language.operators.comparison.php" class="link">比較演算子</a>
      </td>
     </tr>

     <tr>
      <td>left</td>
      <td><code class="literal">&amp;</code></td>
      <td>
       <a href="language.operators.bitwise.php" class="link">ビット演算子</a> そして 
       <a href="language.references.php" class="link">リファレンス</a></td>
     </tr>

     <tr>
      <td>left</td>
      <td><code class="literal">^</code></td>
      <td>
       <a href="language.operators.bitwise.php" class="link">ビット演算子</a>
      </td>
     </tr>

     <tr>
      <td>left</td>
      <td><code class="literal">|</code></td>
      <td>
       <a href="language.operators.bitwise.php" class="link">ビット演算子</a>
      </td>
     </tr>

     <tr>
      <td>left</td>
      <td><code class="literal">&amp;&amp;</code></td>
      <td>
       <a href="language.operators.logical.php" class="link">論理演算子</a>
      </td>
     </tr>

     <tr>
      <td>left</td>
      <td><code class="literal">||</code></td>
      <td>
       <a href="language.operators.logical.php" class="link">論理演算子</a>
      </td>
     </tr>

     <tr>
      <td>right</td>
      <td><code class="literal">??</code></td>
      <td>
       <a href="language.operators.comparison.php#language.operators.comparison.coalesce" class="link">NULL合体演算子</a>
      </td>
     </tr>

     <tr>
      <td>結合しない</td>
      <td><code class="literal">? :</code></td>
      <td>
       <a href="language.operators.comparison.php#language.operators.comparison.ternary" class="link">三項演算子</a>
       (PHP 8.0.0 より前のバージョンでは、左結合でした)
      </td>
     </tr>

     <tr>
      <td>right</td>
      <td>
       <code class="literal">=</code> 
       <code class="literal">+=</code> 
       <code class="literal">-=</code> 
       <code class="literal">*=</code> 
       <code class="literal">**=</code> 
       <code class="literal">/=</code> 
       <code class="literal">.=</code> 
       <code class="literal">%=</code> 
       <code class="literal">&amp;=</code> 
       <code class="literal">|=</code> 
       <code class="literal">^=</code> 
       <code class="literal">&lt;&lt;=</code> 
       <code class="literal">&gt;&gt;=</code>
       <code class="literal">??=</code>
      </td>
      <td>
       <a href="language.operators.assignment.php" class="link">代入演算子</a>
      </td>
     </tr>

     <tr>
      <td>(n/a)</td>
      <td><code class="literal">yield from</code></td>
      <td>
       <a href="language.generators.syntax.php#control-structures.yield.from" class="link">yield from</a>
      </td>
     </tr>

     <tr>
      <td>(n/a)</td>
      <td><code class="literal">yield</code></td>
      <td>
       <a href="language.generators.syntax.php#control-structures.yield" class="link">yield</a>
      </td>
     </tr>

     <tr>
      <td>(n/a)</td>
      <td><code class="literal">print</code></td>
      <td><span class="function"><a href="function.print.php" class="function">print</a></span></td>
     </tr>

     <tr>
      <td>left</td>
      <td><code class="literal">and</code></td>
      <td>
       <a href="language.operators.logical.php" class="link">論理演算子</a>
      </td>
     </tr>

     <tr>
      <td>left</td>
      <td><code class="literal">xor</code></td>
      <td>
       <a href="language.operators.logical.php" class="link">論理演算子</a>
      </td>
     </tr>

     <tr>
      <td>left</td>
      <td><code class="literal">or</code></td>
      <td>
       <a href="language.operators.logical.php" class="link">論理演算子</a>
      </td>
     </tr>

     <tr>
      <td>(n/a)</td>
      <td><code class="literal">throw</code></td>
      <td>
       <a href="language.exceptions.php" class="link">throw</a>
      </td>
     </tr>

    </tbody>
   
  </table>

 </p>
 <p class="para">
  <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 />$a </span><span style="color: #007700">= </span><span style="color: #0000BB">3 </span><span style="color: #007700">* </span><span style="color: #0000BB">3 </span><span style="color: #007700">% </span><span style="color: #0000BB">5</span><span style="color: #007700">; </span><span style="color: #FF8000">// (3 * 3) % 5 = 4<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$a</span><span style="color: #007700">);<br /><br /></span><span style="color: #0000BB">$a </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$b </span><span style="color: #007700">= </span><span style="color: #0000BB">2</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$a </span><span style="color: #007700">= </span><span style="color: #0000BB">$b </span><span style="color: #007700">+= </span><span style="color: #0000BB">3</span><span style="color: #007700">; </span><span style="color: #FF8000">// $a = ($b += 3) -&gt; $a = 5, $b = 5<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$a</span><span style="color: #007700">, </span><span style="color: #0000BB">$b</span><span style="color: #007700">);<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </p>
 <p class="para">
  三項演算子は特に、優先順位を明確にするための括弧が必要となります。
 </p>
 <p class="para">
  <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 />$a </span><span style="color: #007700">= </span><span style="color: #0000BB">true </span><span style="color: #007700">? </span><span style="color: #0000BB">0 </span><span style="color: #007700">: (</span><span style="color: #0000BB">true </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: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$a</span><span style="color: #007700">);<br /><br /></span><span style="color: #FF8000">// PHP 8 以降は以下のように書くことはできません<br />// $a = true ? 0 : true ? 1 : 2;<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
 </p>
 <p class="para">
  演算子の優先順位や結合性は、あくまでも式のグループ分けだけを決めるものであり、評価順を決めるものではありません。
  PHP では一般に、式をどの順番で評価するかは決めていません。
  そのため、特定の順序で式が評価されることを前提としたコードを書いてはいけません。
  PHP のバージョンが変わったり前後のコードが変わったりしたときに、評価順が変わる可能性があるからです。
  <div class="example" id="example-3">
   <p><strong>例3 評価順序は未定義</strong></p>
   <div class="example-contents">
<div class="annotation-non-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$a </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br />echo </span><span style="color: #0000BB">$a </span><span style="color: #007700">+ </span><span style="color: #0000BB">$a</span><span style="color: #007700">++; </span><span style="color: #FF8000">// 2 になるかもしれないし、3 になるかもしれません<br /><br /></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">$array</span><span style="color: #007700">[</span><span style="color: #0000BB">$i</span><span style="color: #007700">] = </span><span style="color: #0000BB">$i</span><span style="color: #007700">++; </span><span style="color: #FF8000">// インデックス 1 をセットするかもしれないし、インデックス 2 をセットするかもしれません<br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
   </div>

  </div>
  <div class="example" id="example-4">
   <p><strong>例4 <code class="literal">+</code>、<code class="literal">-</code>、<code class="literal">.</code> の優先順位</strong></p>
   <div class="example-contents">
<div class="annotation-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$x </span><span style="color: #007700">= </span><span style="color: #0000BB">4</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">// 次の行は、予期せぬ結果になることでしょう<br /></span><span style="color: #007700">echo </span><span style="color: #DD0000">"x minus one equals " </span><span style="color: #007700">. </span><span style="color: #0000BB">$x</span><span style="color: #007700">-</span><span style="color: #0000BB">1 </span><span style="color: #007700">. </span><span style="color: #DD0000">", or so I hope\n"</span><span style="color: #007700">;<br /><br /></span><span style="color: #FF8000">// 期待どおりの結果を得るには、括弧を使って優先順位を指定します<br /></span><span style="color: #007700">echo </span><span style="color: #DD0000">"x minus one equals " </span><span style="color: #007700">. (</span><span style="color: #0000BB">$x</span><span style="color: #007700">-</span><span style="color: #0000BB">1</span><span style="color: #007700">) . </span><span style="color: #DD0000">", or so I hope\n"</span><span style="color: #007700">;<br /><br /></span><span style="color: #FF8000">// このようにはできず、TypeError がスローされます<br /></span><span style="color: #007700">echo ((</span><span style="color: #DD0000">"x minus one equals " </span><span style="color: #007700">. </span><span style="color: #0000BB">$x</span><span style="color: #007700">) - </span><span style="color: #0000BB">1</span><span style="color: #007700">) . </span><span style="color: #DD0000">", or so I hope\n"</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>
-1, or so I hope
-1, or so I hope
Fatal error: Uncaught TypeError: Unsupported operand types: string - int
</pre></div>
   </div>
  </div>
  <div class="example" id="example-5">
   <p><strong>例5 PHP 8 より前のバージョンでは、 <code class="literal">+</code>, <code class="literal">-</code> and <code class="literal">.</code> の優先順位は同じ</strong></p>
   <div class="example-contents">
<div class="annotation-non-interactive phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br />$x </span><span style="color: #007700">= </span><span style="color: #0000BB">4</span><span style="color: #007700">;<br /></span><span style="color: #FF8000">// 次の行は、予期せぬ結果になることでしょう<br /></span><span style="color: #007700">echo </span><span style="color: #DD0000">"x minus one equals " </span><span style="color: #007700">. </span><span style="color: #0000BB">$x</span><span style="color: #007700">-</span><span style="color: #0000BB">1 </span><span style="color: #007700">. </span><span style="color: #DD0000">", or so I hope\n"</span><span style="color: #007700">;<br /><br /></span><span style="color: #FF8000">// なぜなら、これは次のように評価されるからです(PHP 8.0.0 より前のバージョン)<br /></span><span style="color: #007700">echo ((</span><span style="color: #DD0000">"x minus one equals " </span><span style="color: #007700">. </span><span style="color: #0000BB">$x</span><span style="color: #007700">) - </span><span style="color: #0000BB">1</span><span style="color: #007700">) . </span><span style="color: #DD0000">", or so I hope\n"</span><span style="color: #007700">;<br /><br /></span><span style="color: #FF8000">// 期待どおりの結果を得るには、括弧を使って優先順位を指定します<br /></span><span style="color: #007700">echo </span><span style="color: #DD0000">"x minus one equals " </span><span style="color: #007700">. (</span><span style="color: #0000BB">$x</span><span style="color: #007700">-</span><span style="color: #0000BB">1</span><span style="color: #007700">) . </span><span style="color: #DD0000">", or so I hope\n"</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>
-1, or so I hope
-1, or so I hope
x minus one equals 3, or so I hope
</pre></div>
   </div>
  </div>
 </p>
 <blockquote class="note"><p><strong class="note">注意</strong>: 
  <p class="para">
   <code class="literal">=</code> は他のほとんどの演算子よりも優先順位が低いはずなのにもかかわらず、
   PHP は依然として <code class="literal">if (!$a = foo())</code>
   のような式も許します。この場合は <code class="literal">foo()</code> の戻り値が
   <var class="varname">$a</var> に代入されます。
  </p>
 </p></blockquote>
 <div class="sect2">
  <h3 class="title">変更履歴</h3>
  <table class="doctable informaltable">
   
    <thead>
     <tr>
      <th>バージョン</th>
      <th>説明</th>
     </tr>

    </thead>

    <tbody class="tbody">
     <tr>
      <td>8.0.0</td>
      <td>
       文字列の連結 (<code class="literal">.</code>) 
       の優先順位は、
       算術演算子の加算/減算
       (<code class="literal">+</code> および <code class="literal">-</code>)
       と ビットシフト演算子
       (<code class="literal">&lt;&lt;</code> および <code class="literal">&gt;&gt;</code>);
       よりも低くなりました。
       これより前のバージョンでは、文字列の連結は
       <code class="literal">+</code> と <code class="literal">-</code>
       と同じ優先順位を持ち、
       <code class="literal">&lt;&lt;</code> と <code class="literal">&gt;&gt;</code>
       よりは高い優先順位を持っていました。
      </td>
     </tr>

     <tr>
      <td>8.0.0</td>
      <td>
       三項演算子 (<code class="literal">? :</code>) は、
       どの演算とも結合しなくなりました。
       これより前のバージョンでは、左結合でした。
      </td>
     </tr>

     <tr>
      <td>7.4.0</td>
      <td>
       三項演算子(<code class="literal">? :</code>) が左結合であることに依存すること、
       つまり、括弧で囲わずに三項演算子をネストすることは推奨されなくなりました。
      </td>
     </tr>

     <tr>
      <td>7.4.0</td>
      <td>
       文字列の連結 (<code class="literal">.</code>) 演算と、
       算術演算子の加算/減算
       (<code class="literal">+</code> および <code class="literal">-</code>)
       と ビットシフト演算子
       (<code class="literal">&lt;&lt;</code> および <code class="literal">&gt;&gt;</code>);
       の優先順位に依存するコードは、推奨されなくなりました。
       つまり、これらを括弧を使わずに一緒に使うことは推奨されなくなりました。
      </td>
     </tr>

    </tbody>
   
  </table>

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