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

contributors($setup);

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

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

  <div class="sect3" id="migration74.incompatible.core.non-array-access">
   <h4 class="title">Массивоподобное обращение к немассивам</h4>

   <p class="para">
    Попытка использовать значения с типом <span class="type"><a href="language.types.null.php" class="type null">null</a></span>, <span class="type"><a href="language.types.boolean.php" class="type bool">bool</a></span>,
    <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.resource.php" class="type resource">resource</a></span> как массив
    (например, <code class="literal">$null[&quot;key&quot;]</code>) теперь создаст уведомление.
   </p>
  </div>

  <div class="sect3" id="migration74.incompatible.core.get-declared-classes">
   <h4 class="title">Функция <span class="function"><a href="function.get-declared-classes.php" class="function">get_declared_classes()</a></span></h4>

   <p class="para">
    Функция <span class="function"><a href="function.get-declared-classes.php" class="function">get_declared_classes()</a></span> больше
    не возвращает анонимные классы, которые ещё не были созданы.
   </p>
  </div>

  <div class="sect3" id="migration74.incompatible.core.fn">
   <h4 class="title">Ключевое слово <code class="literal">fn</code></h4>

   <p class="para">
    Литерал <code class="literal">fn</code> теперь зарезервированное ключевое слово. В частности,
    его больше не разрешено указывать как имя функции или класса.
    Но при этом, этим ключевым словом разрешено назвать имя метода или константы в классе.
   </p>
  </div>

  <div class="sect3" id="migration74.incompatible.core.php-tag">
   <h4 class="title">Тег <code class="literal">&lt;?php</code> в конце файла</h4>

   <p class="para">
    Запись <code class="literal">&lt;?php</code> в конце файла (без завершающей новой строки)
    теперь будет интерпретироваться как открывающий тег PHP.
    Ранее она обрабатывалась либо как короткий открывающий тег
    с последующим литералом <code class="literal">php</code>
    и приводил к синтаксической ошибке (при <code class="literal">short_open_tag=1</code>),
    либо воспринимался как строковый литерал <code class="literal">&lt;?php</code>
    (в случае <code class="literal">short_open_tag=0</code>).
   </p>
  </div>

  <div class="sect3" id="migration74.incompatible.core.stream-wrappers">
   <h4 class="title">Потоковые обёртки</h4>

   <p class="para">
    При включении данных потока выражениями include или require
    метод <span class="methodname"><a href="streamwrapper.stream-set-option.php" class="methodname">streamWrapper::stream_set_option()</a></span>
    будет вызываться с параметром <strong><code><a href="stream.constants.php#constant.stream-option-read-buffer">STREAM_OPTION_READ_BUFFER</a></code></strong>.
    Для пользовательских потоковых обёрток, возможно, потребуется реализация
    метода <span class="methodname"><a href="streamwrapper.stream-set-option.php" class="methodname">streamWrapper::stream_set_option()</a></span>,
    чтобы убрать предупреждение (как правило, хватает только возврата <strong><code><a href="reserved.constants.php#constant.false">false</a></code></strong>).
   </p>
  </div>

  <div class="sect3" id="migration74.incompatible.core.serialization">
   <h4 class="title">Сериализация</h4>

   <p class="para">
    Удалён формат сериализации <code class="literal">o</code>.
    Поскольку сам PHP им не пользуется, он мог только нарушить десериализацию строк, созданных вручную.
   </p>
  </div>

  <div class="sect3" id="migration74.incompatible.core.password-algorithm-constants">
   <h4 class="title">Константы алгоритма пароля</h4>

   <p class="para">
    Идентификаторы алгоритма хеширования паролей теперь обнуляемые строки, а не целые числа.
   </p>

   <ul class="itemizedlist">
    <li class="listitem">
     <span class="simpara">
      <strong><code><a href="password.constants.php#constant.password-default">PASSWORD_DEFAULT</a></code></strong> раньше было целочисленным 1; теперь строка &#039;2y&#039; (в PHP 7.4.0, 7.4.1 и 7.4.2 было <strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong>)
     </span>
    </li>
    <li class="listitem">
     <span class="simpara">
      <strong><code><a href="password.constants.php#constant.password-bcrypt">PASSWORD_BCRYPT</a></code></strong> раньше было целочисленным 1; теперь строка &#039;2y&#039;
     </span>
    </li>
    <li class="listitem">
     <span class="simpara">
      <strong><code><a href="password.constants.php#constant.password-argon2i">PASSWORD_ARGON2I</a></code></strong> раньше было целочисленным 2; теперь строка &#039;argon2i&#039;
     </span>
    </li>
    <li class="listitem">
     <span class="simpara">
      <strong><code><a href="password.constants.php#constant.password-argon2id">PASSWORD_ARGON2ID</a></code></strong> раньше было целочисленным 3; теперь строка &#039;argon2id&#039;
     </span>
    </li>
   </ul>

   <p class="para">
    Приложения, правильно использующие константы PASSWORD_DEFAULT,
    PASSWORD_BCRYPT, PASSWORD_ARGON2I и PASSWORD_ARGON2ID, будут
    работать как и раньше.
   </p>
  </div>

  <div class="sect3" id="migration74.incompatible.core.htmlentities">
   <h4 class="title">Функция <span class="function"><a href="function.htmlentities.php" class="function">htmlentities()</a></span></h4>

   <p class="para">
    Функция <span class="function"><a href="function.htmlentities.php" class="function">htmlentities()</a></span> теперь будет выдавать уведомление
    (вместо предупреждения уровня E_STRICT), если она используется
    с кодировкой, для которой поддерживается только преобразование основных символов.
    В этом случае она эквивалентна использованию <span class="function"><a href="function.htmlspecialchars.php" class="function">htmlspecialchars()</a></span>.
   </p>
  </div>

  <div class="sect3" id="migration74.incompatible.core.fread-fwrite">
   <h4 class="title">Функции <span class="function"><a href="function.fread.php" class="function">fread()</a></span> и <span class="function"><a href="function.fwrite.php" class="function">fwrite()</a></span></h4>

   <p class="para">
    Функции <span class="function"><a href="function.fread.php" class="function">fread()</a></span> и <span class="function"><a href="function.fwrite.php" class="function">fwrite()</a></span> теперь будут
    возвращать <strong><code><a href="reserved.constants.php#constant.false">false</a></code></strong>, если операция не удалась.
    Ранее возвращалась пустая строка или 0.
    К ошибкам EAGAIN/EWOULDBLOCK это не относится.
   </p>
   <p class="para">
    Эти функции теперь также вызывают уведомление при неудачном выполнении,
    например, при записи в файловый ресурс, предназначенный только для чтения.
   </p>
  </div>

 </div>

 <div class="sect2" id="migration74.incompatible.bcmath">
  <h3 class="title">Вычисления над числами с произвольной точностью BCMath</h3>

  <p class="para">
   Теперь функции BCMath будут выдавать предупреждения,
   если передано число с ошибкой, например, <code class="literal">&quot;32foo&quot;</code>.
   Подобный аргумент, как и раньше, будет интерпретирован как ноль.
  </p>
 </div>

 <div class="sect2" id="migration74.incompatible.curl">
  <h3 class="title">CURL</h3>

  <p class="para">
   Попытка сериализации класса <span class="classname"><a href="class.curlfile.php" class="classname">CURLFile</a></span> теперь создаст исключение.
   Ранее исключение выбрасывалось только при десериализации.
  </p>
  <p class="para">
   Использование <strong><code><a href="curl.constants.php#constant.curlpipe-http1">CURLPIPE_HTTP1</a></code></strong> объявлено устаревшим,
   и не будет поддерживаться с версии cURL 7.62.0.
  </p>
  <p class="para">
   Параметр <code class="literal">$version</code> функции <span class="function"><a href="function.curl-version.php" class="function">curl_version()</a></span>
   объявлен устаревшим. Если передаётся значение,
   не равное <strong><code><a href="curl.constants.php#constant.curlversion-now">CURLVERSION_NOW</a></code></strong> по умолчанию,
   будет вызвано предупреждение, а параметр проигнорирован.
  </p>
 </div>

 <div class="sect2" id="migration74.incompatible.datetime">
  <h3 class="title">Дата и время</h3>

  <p class="para">
   Вызов функции <span class="function"><a href="function.var-dump.php" class="function">var_dump()</a></span> или похожих отладочных функций на экземпляре класса
   <span class="classname"><a href="class.datetime.php" class="classname">DateTime</a></span> или <span class="classname"><a href="class.datetimeimmutable.php" class="classname">DateTimeImmutable</a></span>
   больше не оставляет внутренние свойства объекта доступными для прямого считывания или записи при очередном обращении.
  </p>
  <p class="para">
   Сравнение объектов <span class="classname"><a href="class.dateinterval.php" class="classname">DateInterval</a></span>
   (с использованием <code class="literal">==</code>, <code class="literal">&lt;</code> и т.д.) теперь создаёт
   предупреждение и всегда возвращает <strong><code><a href="reserved.constants.php#constant.false">false</a></code></strong>. Ранее все объекты <span class="classname"><a href="class.dateinterval.php" class="classname">DateInterval</a></span>
   считались одинаковыми, если у них не было свойств.
  </p>
 </div>

 <div class="sect2" id="migration74.incompatible.intl">
  <h3 class="title">Intl</h3>

  <p class="para">
   Значение параметров по умолчанию в функциях <span class="function"><a href="function.idn-to-ascii.php" class="function">idn_to_ascii()</a></span> и
   <span class="function"><a href="function.idn-to-utf8.php" class="function">idn_to_utf8()</a></span> теперь <strong><code><a href="intl.constants.php#constant.intl-idna-variant-uts46">INTL_IDNA_VARIANT_UTS46</a></code></strong>
   вместо устаревшего <strong><code><a href="intl.constants.php#constant.intl-idna-variant-2003">INTL_IDNA_VARIANT_2003</a></code></strong>.
  </p>
 </div>

 <div class="sect2" id="migration74.incompatible.mysqli">
  <h3 class="title">MySQLi</h3>

  <p class="para">
   Функциональность встроенного сервера была удалена. Она была сломана как минимум с PHP 7.0.
  </p>
  <p class="para">
   Недокументированное свойство <code class="literal">mysqli::$stat</code> было удалено
   в пользу использования <span class="methodname"><a href="mysqli.stat.php" class="methodname">mysqli::stat()</a></span>.
  </p>
 </div>

 <div class="sect2" id="migration74.incompatible.openssl">
  <h3 class="title">OpenSSL</h3>

  <p class="para">
   Функция <span class="function"><a href="function.openssl-random-pseudo-bytes.php" class="function">openssl_random_pseudo_bytes()</a></span> теперь будет
   выбрасывать исключение в тех же ситуациях, что и функция <span class="function"><a href="function.random-bytes.php" class="function">random_bytes()</a></span>.
   В частности, выбрасывается исключение <span class="classname"><a href="class.error.php" class="classname">Error</a></span>, если количество запрошенных байтов
   меньше или равно нулю. Исключение <span class="classname"><a href="class.exception.php" class="classname">Exception</a></span> выбрасывается,
   если не получена достаточная случайность.
   Аргумент <code class="literal">$crypto_strong</code> гарантированно будет равен <strong><code><a href="reserved.constants.php#constant.true">true</a></code></strong>,
   если функция ничего не выбрасывает, поэтому явно проверять его не нужно.
  </p>
 </div>

 <div class="sect2" id="migration74.incompatible.pcre">
  <h3 class="title">Регулярные выражения (совместимые Perl)</h3>

  <p class="para">
   При использовании флага <strong><code><a href="pcre.constants.php#constant.preg-unmatched-as-null">PREG_UNMATCHED_AS_NULL</a></code></strong>,
   завершающие несовпадающие подмаски теперь будут иметь значение <strong><code><a href="reserved.constants.php#constant.null">null</a></code></strong> (или
   <code class="literal">[null, -1]</code>, если включено сохранение позиции подмаски).
   Это означает, что размер <code class="literal">$matches</code> всегда будет одинаковым.
  </p>
 </div>

 <div class="sect2" id="migration74.incompatible.pdo">
  <h3 class="title">Объекты данных PHP (PDO)</h3>

  <p class="para">
   Попытка сериализовать экземпляр <span class="classname"><a href="class.pdo.php" class="classname">PDO</a></span> или
   <span class="classname"><a href="class.pdostatement.php" class="classname">PDOStatement</a></span> теперь создаст
   <span class="classname"><a href="class.exception.php" class="classname">Exception</a></span>, а не <span class="classname"><a href="class.pdoexception.php" class="classname">PDOException</a></span>,
   по аналогии с другими внутренними классами, которые не поддерживают сериализацию.
  </p>
 </div>

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

  <p class="para">
   Объекты Reflection теперь создают исключение, если попробовать
   их сериализовать. Сериализация объектов Reflection никогда не поддерживалась
   и приводила к повреждению объектов Reflection. Сейчас это было явно запрещено.
  </p>

  <p class="para">
   Изменились значения констант классов <span class="classname"><a href="class.reflectionclassconstant.php" class="classname">ReflectionClassConstant</a></span>,
   <span class="classname"><a href="class.reflectionmethod.php" class="classname">ReflectionMethod</a></span> и <span class="classname"><a href="class.reflectionproperty.php" class="classname">ReflectionProperty</a></span>.
  </p>
 </div>

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

  <p class="para">
   Вызов <span class="function"><a href="function.get-object-vars.php" class="function">get_object_vars()</a></span> с экземпляром
   <span class="classname"><a href="class.arrayobject.php" class="classname">ArrayObject</a></span> теперь всегда будет возвращать свойства самого
   <span class="classname"><a href="class.arrayobject.php" class="classname">ArrayObject</a></span> (или подкласса). Ранее он возвращал значения упакованного
   массива/объекта, если не был указан флаг <strong><code><a href="class.arrayobject.php#arrayobject.constants.std-prop-list">ArrayObject::STD_PROP_LIST</a></code></strong>.
  </p>
  <p class="para">
   Другие затронутые операции:
  </p>
  <ul class="itemizedlist">
   <li class="listitem">
    <span class="simpara">
     <span class="methodname"><strong>ReflectionObject::getProperties()</strong></span>
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     <span class="function"><a href="function.reset.php" class="function">reset()</a></span>, <span class="function"><a href="function.current.php" class="function">current()</a></span> и т.д.
     Используйте вместо этого методы <span class="interfacename"><a href="class.iterator.php" class="interfacename">Iterator</a></span>.
    </span>
   </li>
   <li class="listitem">
    <span class="simpara">
     Вероятно, все остальное работает со свойствами объекта при доступе в виде списка,
     например, <span class="function"><a href="function.array-walk.php" class="function">array_walk()</a></span>.
    </span>
   </li>
  </ul>
  <p class="para">
   На приведение типа <code class="literal">(array)</code> эти изменения не повлияют.
   Они по-прежнему возвращают либо упакованный массив, либо свойства <span class="classname"><a href="class.arrayobject.php" class="classname">ArrayObject</a></span>,
   в зависимости от того, используется ли флаг <strong><code><a href="class.arrayobject.php#arrayobject.constants.std-prop-list">ArrayObject::STD_PROP_LIST</a></code></strong>.
  </p>
  <p class="para">
   Метод <span class="methodname"><a href="splpriorityqueue.setextractflags.php" class="methodname">SplPriorityQueue::setExtractFlags()</a></span> выбросит
   исключение, если передан ноль. Ранее это приводило к отлавливаемой
   фатальной ошибке при следующей операции извлечения.
  </p>
  <p class="para">
   <span class="classname"><a href="class.arrayobject.php" class="classname">ArrayObject</a></span>, <span class="classname"><a href="class.arrayiterator.php" class="classname">ArrayIterator</a></span>,
   <span class="classname"><a href="class.spldoublylinkedlist.php" class="classname">SplDoublyLinkedList</a></span> и <span class="classname"><a href="class.splobjectstorage.php" class="classname">SplObjectStorage</a></span>
   теперь поддерживают <code class="literal">__serialize()</code> и  <code class="literal">__unserialize()</code>
   в дополнение к интерфейсу <span class="interfacename"><a href="class.serializable.php" class="interfacename">Serializable</a></span>.
   Поэтому теперь созданные в более старых версиях PHP сериализованные данные,
   всё ещё могут быть неверно обработаны. Однако новые созданные сериализованные данные в PHP 7.4,
   не будут восприниматься в более старых версиях.
  </p>
 </div>

 <div class="sect2" id="migration74.incompatible.tokenizer">
  <h3 class="title">Лексер (Tokenizer)</h3>

  <p class="para">
   Функция <span class="function"><a href="function.token-get-all.php" class="function">token_get_all()</a></span> теперь отобразит метку
   <strong><code><a href="tokens.php#constant.t-bad-character">T_BAD_CHARACTER</a></code></strong> в случае обнаружения непредвиденных символов в потоке меток.
  </p>
 </div>

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

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

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