## Изменения, которые ломают обратную совместимость

### Ядро PHP

#### Интерпретация закрывающего идентификатора Heredoc/Nowdoc

Благодаря введению гибкого синтаксиса heredoc/nowdoc, doc-строки, содержащие закрывающие идентификаторы внутри своего тела, могут вызвать синтаксические ошибки или изменения в интерпретации. Пример:

    <?php

    $str = <<<FOO
    abcdefg
       FOO
    FOO;

    ?>

С отступом `FOO` ранее не имел особого значения. Теперь он будет интерпретироваться как конец heredoc-строки и следующий `FOO;` приведёт к синтаксической ошибке. Эта проблема всегда может быть решена путём выбора закрывающего идентификатора, который не используется в содержимом строки.

#### Генерирование предупреждения в continue, используемом в switch

Выражения `continue`, используемые в структурах управления потока `switch` теперь будет выдавать предупреждение. В PHP такие выражения `continue` эквиваленты `break`, в то время, как в других языках они ведут себя как `continue 2`.

    <?php

    while ($foo) {
        switch ($bar) {
          case "baz":
             continue;
             // Предупреждение: "continue" эквивалентен
             //          "break". Возможно, вы имели в виду "continue 2"?
       }
    }

    ?>

#### Строгая интерпретация целых строковых ключей на ArrayAccess

Доступ к массиву типа `$obj["123"]`, где `$obj` реализует интерфейс ArrayAccess, а `"123"` — целочисленный строковый литерал, больше не приведёт к неявному преобразованию в целое число, т. е. `$obj->offsetGet("123")` вместо `$obj->offsetGet(123)`. Это соответствует существующему поведению для нелитеральных значений. Поведение массивов никак не изменилось, они продолжают неявно преобразовывать целые строковые ключи в целые числа.

#### Статические свойства больше не разделяются присвоением по ссылке

В PHP статические свойства совместно используются наследующими классами, если статическое свойство явно не переопределено в дочернем классе. Однако из-за ошибки реализации можно было отделить статические свойства, присвоив их по ссылке. Эта лазейка была исправлена.

    <?php

    class Test
    {
        public static $x = 0;
    }

    class Test2 extends Test { }

    Test2::$x = &$x;
    $x = 1;

    var_dump(Test::$x, Test2::$x);
    // Раньше:  int(0), int(1)
    // Теперь: int(1), int(1)

    ?>

#### Ссылки, возвращаемые при доступе к массиву или свойству немедленно распаковываются

Ссылки, возвращаемые доступом к массиву и свойству, теперь распаковываются как часть доступа. Это означает, что больше невозможно изменить ссылку между доступом и использованием доступного значения:

    <?php

    $arr = [1];
    $ref =& $arr[0];
    var_dump($arr[0] + ($arr[0] = 2));
    // Раньше: int(4), Теперь: int(3)

    ?>

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

#### Распаковка аргумента со значением Traversable с нечисловыми ключами больше не поддерживается

Распаковка аргументов перестала работать со значением Traversable с нечисловыми ключами. Следующий код работает в PHP 5.6-7.2 по ошибке.

    <?php

    function foo(...$args)
    {
        var_dump($args);
    }

    function gen()
    {
        yield 1.23 => 123;
    }

    foo(...gen());

    ?>

#### Разное

Утилиту ext_skel полностью переработали с новыми опциями, а некоторые старые опции удалили. Теперь она написана на PHP и не имеет внешних зависимостей.

Поддержка BeOS была прекращена.

Исключения, выброшенные из-за автоматического преобразования предупреждений в исключения в режиме `EH_THROW` (например, некоторые исключения DateTime), больше не заполняют состояние error_get_last(). Таким образом, они теперь работают так же, как вручную выброшенные исключения.

Исключение TypeError теперь указывает на правильные типы `int` и `bool` вместо `integer` и `boolean`, соответственно.

Про неопределённые переменные, переданные в compact(), теперь будет сообщено уведомлением.

Функция getimagesize() и связанные с ней функции теперь сообщают mime-типы изображений BMP как `image/bmp` вместо `image/x-ms-bmp`, поскольку первый зарегистрирован в IANA (смотрите » RFC 7903).

Функция stream_socket_get_name() теперь возвращает адреса IPv6, заключённые в квадратные скобки. Например, будет возвращена строка `"[::1]:1337"` вместо `"::1:1337"`.

### Произвольной точности математика BCMath

Все предупреждения, выброшенные функциями BCMath, теперь используют обработку ошибок PHP. Раньше некоторые предупреждения были непосредственно отправлены в поток stderr.

Функции bcmul() и bcpow() теперь возвращают числа с запрошенным масштабом. Раньше возвращаемые числа могли опускать завершающие десятичные нули.

### IMAP, POP3 и NNTP

Логины rsh/ssh по умолчанию отключены. Используйте imap.enable_insecure_rsh, если вы хотите включить их. Обратите внимание, что библиотека IMAP не фильтрует имена почтовых ящиков перед передачей их команде rsh/ssh, таким образом, передача ненадёжных данных этой функции с включённым rsh/ssh небезопасна.

### Мультибайтовые строки

Из-за дополнительной поддержки именованных фрагментов, паттерны `mb_ereg_*()` с использованием именованных фрагментов будут вести себя по-разному. В частности, именованные фрагменты будут частью совпадений, а функция mb_ereg_replace() будет интерпретировать дополнительный синтаксис. Смотрите Именованные фрагменты для получения дополнительной информации.

### Улучшенный модуль MySQL

Подготовленные запросы теперь правильно указывают на дробные секунды для столбцов `DATETIME`, `TIME` и `TIMESTAMP` с указателем десятичных знаков (например, `TIMESTAMP(6)` при использовании микросекунд). Раньше часть дробных секунд была просто опущена из возвращаемых значений.

### Функции MySQL (PDO_MYSQL)

Подготовленные запросы теперь правильно указывают на дробные секунды для столбцов `DATETIME`, `TIME` и `TIMESTAMP` со спецификатором десятичных знаков (например, `TIMESTAMP(6)` при использовании микросекунд). Ранее, дробная часть секунд была просто опущена из возвращаемых значений. Обратите внимание, что это влияет только на использование PDO_MYSQL с отключённой эмуляцией подготовленных запросов (например, с использованием нативной функциональности). Запросы, использующие соединения, у которых задана опция `PDO::ATTR_EMULATE_PREPARES`=`true` (значение по умолчанию), не были затронуты данным исправлением ошибки и уже получали корректные значения долей секунды от движка.

### Reflection

Экспорт объектов Reflection в строку теперь использует `int`) и `bool`) вместо `integer` and `boolean`, соответственно.

### Стандартная библиотека PHP (SPL)

Если автозагрузчик SPL выбрасывает исключение, последующие автозагрузчики не будут выполняться. Раньше все автозагрузчики выполнялись, а исключения объединялись в цепочку вызовов.

### SimpleXML

Математические операции, которые включают объекты SimpleXML, теперь будут обрабатывать текст как целое число (int) или число с плавающей точкой (float), в зависимости от того, что является более подходящим. Раньше значения обрабатывались как целые числа (integer) без каких-либо условий.

### Входящие Cookies

Начиная с PHP 7.3.23 имена входящих cookie больше не декодируются из URL-закодированной строки из соображений безопасности.

`↑` and `↓` to navigate • `Enter` to select • `Esc` to close • `/` to open