<?php
include_once $_SERVER['DOCUMENT_ROOT'] . '/include/shared-manual.inc';
$TOC = array();
$TOC_DEPRECATED = array();
$PARENTS = array();
include_once dirname(__FILE__) ."/toc/migration73.inc";
$setup = array (
  'home' => 
  array (
    0 => 'index.php',
    1 => 'PHP Manual',
  ),
  'head' => 
  array (
    0 => 'UTF-8',
    1 => 'ru',
  ),
  'this' => 
  array (
    0 => 'migration73.incompatible.php',
    1 => 'Изменения, которые ломают обратную совместимость',
    2 => 'Изменения, которые ломают обратную совместимость',
  ),
  'up' => 
  array (
    0 => 'migration73.php',
    1 => 'Миграция с PHP 7.2.x на PHP 7.3.x',
  ),
  'prev' => 
  array (
    0 => 'migration73.constants.php',
    1 => 'Новые глобальные константы',
  ),
  'next' => 
  array (
    0 => 'migration73.deprecated.php',
    1 => 'Функционал, объявленный устаревшим в PHP 7.3.x',
  ),
  'alternatives' => 
  array (
  ),
  'source' => 
  array (
    'lang' => 'ru',
    'path' => 'appendices/migration73/incompatible.xml',
  ),
  'history' => 
  array (
  ),
);
$setup["toc"] = $TOC;
$setup["toc_deprecated"] = $TOC_DEPRECATED;
$setup["parents"] = $PARENTS;
manual_setup($setup);

contributors($setup);

?>
<div id="migration73.incompatible" class="sect1">
 <h2 class="title">Изменения, которые ломают обратную совместимость</h2>

 <div class="sect2" id="migration73.incompatible.core">
  <h3 class="title">Ядро PHP</h3>

  <div class="sect3" id="migration73.incompatible.core.heredoc-nowdoc">
   <h4 class="title">Интерпретация закрывающего идентификатора Heredoc/Nowdoc</h4>

   <p class="para">
    Благодаря введению <a href="migration73.new-features.php#migration73.new-features.core.heredoc" class="link">гибкого синтаксиса heredoc/nowdoc</a>,
    doc-строки, содержащие закрывающие идентификаторы внутри своего тела,
    могут вызвать синтаксические ошибки или изменения в интерпретации. Пример:
    <div class="informalexample">
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />$str </span><span style="color: #007700">= &lt;&lt;&lt;FOO<br /></span><span style="color: #DD0000">abcdefg<br /></span><span style="color: #007700">   FOO<br /></span><span style="color: #0000BB">FOO</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
    С отступом <code class="literal">FOO</code> ранее не имел особого значения.
    Теперь он будет интерпретироваться как конец heredoc-строки
    и следующий <code class="literal">FOO;</code> приведёт к синтаксической ошибке.
    Эта проблема всегда может быть решена путём выбора закрывающего идентификатора,
    который не используется в содержимом строки.
   </p>
  </div>

  <div class="sect3" id="migration73.incompatible.core.continue-targeting-switch">
   <h4 class="title">Генерирование предупреждения в continue, используемом в switch</h4>

   <p class="para">
    Выражения <code class="literal">continue</code>, используемые в структурах управления потока <code class="literal">switch</code>
    теперь будет выдавать предупреждение. В PHP такие выражения
    <code class="literal">continue</code> эквиваленты
    <code class="literal">break</code>, в то время, как в других языках они ведут себя как <code class="literal">continue 2</code>.
    <div class="informalexample">
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">while (</span><span style="color: #0000BB">$foo</span><span style="color: #007700">) {<br />    switch (</span><span style="color: #0000BB">$bar</span><span style="color: #007700">) {<br />      case </span><span style="color: #DD0000">"baz"</span><span style="color: #007700">:<br />         continue;<br />         </span><span style="color: #FF8000">// Предупреждение: "continue" эквивалентен<br />         //          "break". Возможно, вы имели в виду "continue 2"?<br />   </span><span style="color: #007700">}<br />}<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

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

  <div class="sect3" id="migration73.incompatible.core.arrayaccess">
   <h4 class="title">Строгая интерпретация целых строковых ключей на ArrayAccess</h4>

   <p class="para">
    Доступ к массиву типа <code class="literal">$obj[&quot;123&quot;]</code>,
    где <code class="literal">$obj</code> реализует интерфейс <span class="classname"><a href="class.arrayaccess.php" class="classname">ArrayAccess</a></span>,
    а <code class="literal">&quot;123&quot;</code> — целочисленный строковый литерал,
    больше не приведёт к неявному преобразованию в целое число,
    т. е. <code class="literal">$obj-&gt;offsetGet(&quot;123&quot;)</code> вместо <code class="literal">$obj-&gt;offsetGet(123)</code>.
    Это соответствует существующему поведению для нелитеральных значений.
    Поведение массивов никак не изменилось, они продолжают неявно преобразовывать целые строковые ключи в целые числа.
   </p>
  </div>

  <div class="sect3" id="migration73.incompatible.core.static-properties">
   <h4 class="title">Статические свойства больше не разделяются присвоением по ссылке</h4>

   <p class="para">
    В PHP статические свойства совместно используются наследующими классами,
    если статическое свойство явно не переопределено в дочернем классе.
    Однако из-за ошибки реализации можно было отделить статические свойства, присвоив их по ссылке.
    Эта лазейка была исправлена.
    <div class="informalexample">
     <div class="example-contents">
<div class="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<br /></span><span style="color: #007700">{<br />    public static </span><span style="color: #0000BB">$x </span><span style="color: #007700">= </span><span style="color: #0000BB">0</span><span style="color: #007700">;<br />}<br /><br />class </span><span style="color: #0000BB">Test2 </span><span style="color: #007700">extends </span><span style="color: #0000BB">Test </span><span style="color: #007700">{ }<br /><br /></span><span style="color: #0000BB">Test2</span><span style="color: #007700">::</span><span style="color: #0000BB">$x </span><span style="color: #007700">= &amp;</span><span style="color: #0000BB">$x</span><span style="color: #007700">;<br /></span><span style="color: #0000BB">$x </span><span style="color: #007700">= </span><span style="color: #0000BB">1</span><span style="color: #007700">;<br /><br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">Test</span><span style="color: #007700">::</span><span style="color: #0000BB">$x</span><span style="color: #007700">, </span><span style="color: #0000BB">Test2</span><span style="color: #007700">::</span><span style="color: #0000BB">$x</span><span style="color: #007700">);<br /></span><span style="color: #FF8000">// Раньше:  int(0), int(1)<br />// Теперь: int(1), int(1)<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

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

  <div class="sect3" id="migration73.incompatible.core.reference-unwrapping">
   <h4 class="title">Ссылки, возвращаемые при доступе к массиву или свойству немедленно распаковываются</h4>

   <p class="para">
    Ссылки, возвращаемые доступом к массиву и свойству, теперь распаковываются как часть доступа.
    Это означает, что больше невозможно изменить ссылку между доступом и использованием доступного значения:
    <div class="informalexample">
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br />$arr </span><span style="color: #007700">= [</span><span style="color: #0000BB">1</span><span style="color: #007700">];<br /></span><span style="color: #0000BB">$ref </span><span style="color: #007700">=&amp; </span><span style="color: #0000BB">$arr</span><span style="color: #007700">[</span><span style="color: #0000BB">0</span><span style="color: #007700">];<br /></span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$arr</span><span style="color: #007700">[</span><span style="color: #0000BB">0</span><span style="color: #007700">] + (</span><span style="color: #0000BB">$arr</span><span style="color: #007700">[</span><span style="color: #0000BB">0</span><span style="color: #007700">] = </span><span style="color: #0000BB">2</span><span style="color: #007700">));<br /></span><span style="color: #FF8000">// Раньше: int(4), Теперь: int(3)<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

    </div>
    Это делает поведение ссылок и без ссылок согласованным.
    Обратите внимание, что чтение и запись значения внутри одного выражения остаётся неопределённым поведением и может измениться в будущем.
   </p>
  </div>

  <div class="sect3" id="migration73.incompatible.core.traversable-unpacking">
   <h4 class="title">Распаковка аргумента со значением Traversable с нечисловыми ключами больше не поддерживается</h4>

   <p class="para">
    Распаковка аргументов перестала работать со значением <span class="classname"><a href="class.traversable.php" class="classname">Traversable</a></span>
    с нечисловыми ключами. Следующий код работает в PHP 5.6-7.2 по ошибке.
    <div class="informalexample">
     <div class="example-contents">
<div class="phpcode"><code><span style="color: #000000"><span style="color: #0000BB">&lt;?php<br /><br /></span><span style="color: #007700">function </span><span style="color: #0000BB">foo</span><span style="color: #007700">(...</span><span style="color: #0000BB">$args</span><span style="color: #007700">)<br />{<br />    </span><span style="color: #0000BB">var_dump</span><span style="color: #007700">(</span><span style="color: #0000BB">$args</span><span style="color: #007700">);<br />}<br /><br />function </span><span style="color: #0000BB">gen</span><span style="color: #007700">()<br />{<br />    yield </span><span style="color: #0000BB">1.23 </span><span style="color: #007700">=&gt; </span><span style="color: #0000BB">123</span><span style="color: #007700">;<br />}<br /><br /></span><span style="color: #0000BB">foo</span><span style="color: #007700">(...</span><span style="color: #0000BB">gen</span><span style="color: #007700">());<br /><br /></span><span style="color: #0000BB">?&gt;</span></span></code></div>
     </div>

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

  <div class="sect3" id="migration73.incompatible.core.misc">
   <h4 class="title">Разное</h4>

   <p class="para">
    Утилиту <var class="filename">ext_skel</var> полностью переработали с новыми опциями, а некоторые старые опции удалили.
    Теперь она написана на PHP и не имеет внешних зависимостей.
   </p>

   <p class="para">
    Поддержка BeOS была прекращена.
   </p>

   <p class="para">
    Исключения, выброшенные из-за автоматического преобразования предупреждений
    в исключения в режиме <code class="literal">EH_THROW</code>
    (например, некоторые исключения <span class="classname"><a href="class.datetime.php" class="classname">DateTime</a></span>),
    больше не заполняют состояние <span class="function"><a href="function.error-get-last.php" class="function">error_get_last()</a></span>.
    Таким образом, они теперь работают так же, как вручную выброшенные исключения.
   </p>

   <p class="para">
    Исключение <span class="classname"><a href="class.typeerror.php" class="classname">TypeError</a></span> теперь указывает на правильные типы
    <code class="literal">int</code> и <code class="literal">bool</code> вместо
    <code class="literal">integer</code> и <code class="literal">boolean</code>, соответственно.
   </p>

   <p class="para">
    Про неопределённые переменные, переданные в <span class="function"><a href="function.compact.php" class="function">compact()</a></span>,
    теперь будет сообщено уведомлением.
   </p>

   <p class="para">
    Функция <span class="function"><a href="function.getimagesize.php" class="function">getimagesize()</a></span> и связанные с ней функции теперь сообщают
    mime-типы изображений BMP как <code class="literal">image/bmp</code> вместо
    <code class="literal">image/x-ms-bmp</code>, поскольку первый зарегистрирован
    в IANA (смотрите <a href="https://datatracker.ietf.org/doc/html/rfc7903" class="link external">&raquo;&nbsp;RFC 7903</a>).
   </p>

   <p class="para">
    Функция <span class="function"><a href="function.stream-socket-get-name.php" class="function">stream_socket_get_name()</a></span> теперь возвращает адреса IPv6,
    заключённые в квадратные скобки. Например, будет возвращена строка <code class="literal">&quot;[::1]:1337&quot;</code>
    вместо <code class="literal">&quot;::1:1337&quot;</code>.
   </p>
  </div>
 </div>

 <div class="sect2" id="migration73.incompatible.bc">
  <h3 class="title">Произвольной точности математика BCMath</h3>

  <p class="para">
   Все предупреждения, выброшенные <a href="ref.bc.php" class="link">функциями BCMath</a>, теперь используют обработку ошибок PHP.
   Раньше некоторые предупреждения были непосредственно отправлены в поток stderr.
  </p>

  <p class="para">
   Функции <span class="function"><a href="function.bcmul.php" class="function">bcmul()</a></span> и <span class="function"><a href="function.bcpow.php" class="function">bcpow()</a></span> теперь возвращают числа с запрошенным масштабом.
   Раньше возвращаемые числа могли опускать завершающие десятичные нули.
  </p>
 </div>

 <div class="sect2" id="migration73.incompatible.imap">
  <h3 class="title">IMAP, POP3 и NNTP</h3>

  <p class="para">
   Логины <strong class="command">rsh</strong>/<strong class="command">ssh</strong> по умолчанию отключены.
   Используйте <a href="imap.configuration.php#ini.imap.enable-insecure-rsh" class="link">imap.enable_insecure_rsh</a>, если вы хотите включить их.
   Обратите внимание, что библиотека IMAP не фильтрует имена почтовых ящиков
   перед передачей их команде <strong class="command">rsh</strong>/<strong class="command">ssh</strong>,
   таким образом, передача ненадёжных данных этой функции с включённым <strong class="command">rsh</strong>/<strong class="command">ssh</strong> небезопасна.
  </p>
 </div>

 <div class="sect2" id="migration73.incompatible.mbstring">
  <h3 class="title">Мультибайтовые строки</h3>

  <p class="para">
   Из-за дополнительной поддержки именованных фрагментов,
   паттерны <code class="literal">mb_ereg_*()</code> с использованием именованных фрагментов будут вести себя по-разному.
   В частности, именованные фрагменты будут частью совпадений, а функция <span class="function"><a href="function.mb-ereg-replace.php" class="function">mb_ereg_replace()</a></span>
   будет интерпретировать дополнительный синтаксис. Смотрите <a href="migration73.new-features.php#migration73.new-features.mbstring.named-captures" class="link">Именованные
   фрагменты</a> для получения дополнительной информации.
  </p>
 </div>

 <div class="sect2" id="migration73.incompatible.mysqli">
  <h3 class="title">Улучшенный модуль MySQL</h3>

  <p class="para">
   Подготовленные запросы теперь правильно указывают на дробные секунды для столбцов
   <code class="literal">DATETIME</code>, <code class="literal">TIME</code> и
   <code class="literal">TIMESTAMP</code> с указателем десятичных знаков
   (например, <code class="literal">TIMESTAMP(6)</code>  при использовании микросекунд).
   Раньше часть дробных секунд была просто опущена из возвращаемых значений.
  </p>
 </div>

 <div class="sect2" id="migration73.incompatible.pdo-mysql">
  <h3 class="title">Функции MySQL (PDO_MYSQL)</h3>

  <p class="para">
   Подготовленные запросы теперь правильно указывают на дробные секунды для столбцов
   <code class="literal">DATETIME</code>, <code class="literal">TIME</code> и
   <code class="literal">TIMESTAMP</code> со спецификатором десятичных знаков
   (например, <code class="literal">TIMESTAMP(6)</code> при использовании микросекунд).
   Ранее, дробная часть секунд была просто опущена из возвращаемых значений.
   Обратите внимание, что это влияет только на использование <a href="ref.pdo-mysql.php" class="link">PDO_MYSQL</a> с отключённой эмуляцией подготовленных запросов
   (например, с использованием нативной функциональности).
   Запросы, использующие соединения, у которых задана опция <strong><code><a href="pdo.constants.php#pdo.constants.attr-emulate-prepares">PDO::ATTR_EMULATE_PREPARES</a></code></strong>=<strong><code><a href="reserved.constants.php#constant.true">true</a></code></strong>
   (значение по умолчанию), не были затронуты данным исправлением ошибки и уже получали корректные значения долей секунды от движка.
  </p>
 </div>

 <div class="sect2" id="migration73.incompatible.reflection">
  <h3 class="title">Reflection</h3>

  <p class="para">
   Экспорт объектов <a href="book.reflection.php" class="link">Reflection</a> в строку теперь использует
   <code class="literal">int</code>) и <code class="literal">bool</code>) вместо
   <code class="literal">integer</code> and <code class="literal">boolean</code>, соответственно.
  </p>
 </div>

 <div class="sect2" id="migration73.incompatible.spl">
  <h3 class="title">Стандартная библиотека PHP (SPL)</h3>

  <p class="para">
   Если автозагрузчик <a href="book.spl.php" class="link">SPL</a> выбрасывает исключение,
   последующие автозагрузчики не будут выполняться.
   Раньше все автозагрузчики выполнялись, а исключения объединялись в цепочку вызовов.
  </p>
 </div>

 <div class="sect2" id="migration73.incompatible.simplexml">
  <h3 class="title">SimpleXML</h3>

  <p class="para">
   Математические операции, которые включают объекты
   <a href="book.simplexml.php" class="link">SimpleXML</a>, теперь будут обрабатывать текст
   как целое число (<span class="type"><a href="language.types.integer.php" class="type int">int</a></span>) или число с плавающей точкой (<span class="type"><a href="language.types.float.php" class="type float">float</a></span>),
   в зависимости от того, что является более подходящим.
   Раньше значения обрабатывались как целые числа (<span class="type"><a href="language.types.integer.php" class="type integer">integer</a></span>) без каких-либо условий.
  </p>
 </div>

 <div class="sect2" id="migration73.incompatible.cookie-decode">
  <h3 class="title">Входящие Cookies</h3>

  <p class="para">
   Начиная с PHP 7.3.23 <em>имена</em> входящих cookie
   больше не декодируются из URL-закодированной строки из соображений безопасности.
  </p>
 </div>

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