<?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 => 'ru',
  ),
  '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' => 'ru',
    '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">
  Приоритет оператора определяет, насколько «тесно» он связывает между собой два
  выражения. Например, выражение <code class="literal">1 + 5 * 3</code> вычисляется
  как <code class="literal">16</code>, а не <code class="literal">18</code>, поскольку у оператора умножения «*»
  более высокий приоритет, чем у оператора сложения «+». Порядок выполнения операторов
  изменяют круглыми скобками, поэтому
  выражение <code class="literal">(1 + 5) * 3</code> вычисляется как <code class="literal">18</code>.
 </p>
 <p class="para">
  Выполнятся ли операторы с равным приоритетом слева направо
  или справа налево, определяет ассоциативность. Например, оператор «-»
  относится к левоассоциативным, поэтому выражение <code class="literal">1 - 2 - 3</code> сгруппируется
  как <code class="literal">(1 - 2) - 3</code> и пересчитается в <code class="literal">-4</code>.
  При этом оператор «=» относится к правоассоциативным, потому выражение <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>(неассоциативен)</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>правая</td>
      <td>
       <code class="literal">**</code>
      </td>
      <td>
       <a href="language.operators.arithmetic.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">~</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>левая</td>
      <td>instanceof</td>
      <td>
       <a href="language.operators.type.php" class="link">типы</a>
      </td>
     </tr>

     <tr>
      <td>(неассоциативен)</td>
      <td>!</td>
      <td>
       <a href="language.operators.logical.php" class="link">логические операторы</a>
      </td>
     </tr>

     <tr>
      <td>левая</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>левая</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> (<code class="literal">.</code> до PHP 8.0.0)
      </td>
     </tr>

     <tr>
      <td>левая</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>левая</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>левая</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>левая</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>левая</td>
      <td>
       <code class="literal">^</code>
      </td>
      <td>
       <a href="language.operators.bitwise.php" class="link">побитовые операторы</a>
      </td>
     </tr>

     <tr>
      <td>левая</td>
      <td>
       <code class="literal">|</code>
      </td>
      <td>
       <a href="language.operators.bitwise.php" class="link">побитовые операторы</a>
      </td>
     </tr>

     <tr>
      <td>левая</td>
      <td>
       <code class="literal">&amp;&amp;</code>
      </td>
      <td>
       <a href="language.operators.logical.php" class="link">логические операторы</a>
      </td>
     </tr>

     <tr>
      <td>левая</td>
      <td>
       <code class="literal">||</code>
      </td>
      <td>
       <a href="language.operators.logical.php" class="link">логические операторы</a>
      </td>
     </tr>

     <tr>
      <td>правая</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>правая</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>(неассоциативен)</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>(неассоциативен)</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>(неассоциативен)</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>левая</td>
      <td>
       <code class="literal">and</code>
      </td>
      <td>
       <a href="language.operators.logical.php" class="link">логические операторы</a>
      </td>
     </tr>

     <tr>
      <td>левая</td>
      <td>
       <code class="literal">xor</code>
      </td>
      <td>
       <a href="language.operators.logical.php" class="link">логические операторы</a>
      </td>
     </tr>

     <tr>
      <td>левая</td>
      <td>
       <code class="literal">or</code>
      </td>
      <td>
       <a href="language.operators.logical.php" class="link">логические операторы</a>
      </td>
     </tr>

     <tr>
      <td>(неассоциативен)</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 /><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">);</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 /><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;</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 /><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</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 /><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 минус 1 равно " </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">", ну, я надеюсь\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">", ну, я надеюсь\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 минус 1 равно " </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">", ну, я надеюсь\n"</span><span style="color: #007700">;</span></span></code></div>
   </div>

   
<div class="example-contents"><p>
 Результат выполнения приведённого примера:
</p></div>

   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
-1, ну, я надеюсь
-1, ну, я надеюсь
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> и <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 /><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 минус 1 равно " </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">", ну, я надеюсь\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 минус один равно " </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">", ну, я надеюсь\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 минус 1 равно " </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">", ну, я надеюсь\n"</span><span style="color: #007700">;</span></span></code></div>
   </div>

   
<div class="example-contents"><p>
 Результат выполнения приведённого примера:
</p></div>

   <div class="example-contents screen">
<div class="annotation-interactive cdata"><pre>
-1, ну, я надеюсь
-1, ну, я надеюсь
x минус 1 равно 3, ну, я надеюсь
</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>
       при арифметических операциях сложения <code class="literal">+</code> или вычитания <code class="literal">-</code>
       и побитовом сдвиге влево <code class="literal">&lt;&lt;</code> или вправо <code class="literal">&gt;&gt;</code>).
      </td>
     </tr>

     <tr>
      <td>7.4.0</td>
      <td>
       В выражениях с бесскобочным вложением ряда тернарных операторов
       теперь не рекомендуют полагаться на левоассоциативность тернарного оператора <code class="literal">? :</code>.
      </td>
     </tr>

    </tbody>
   
  </table>

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