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

Ядро PHP

Массивоподобное обращение к немассивам

Попытка использовать значения с типом null, bool, int, float или resource как массив (например, $null["key"]) теперь создаст уведомление.

Функция get_declared_classes()

Функция get_declared_classes() больше не возвращает анонимные классы, которые ещё не были созданы.

Ключевое слово fn

Литерал fn теперь зарезервированное ключевое слово. В частности, его больше не разрешено указывать как имя функции или класса. Но при этом, этим ключевым словом разрешено назвать имя метода или константы в классе.

Тег <?php в конце файла

Запись <?php в конце файла (без завершающей новой строки) теперь будет интерпретироваться как открывающий тег PHP. Ранее она обрабатывалась либо как короткий открывающий тег с последующим литералом php и приводил к синтаксической ошибке (при short_open_tag=1), либо воспринимался как строковый литерал <?php (в случае short_open_tag=0).

Потоковые обёртки

При включении данных потока выражениями include или require метод streamWrapper::stream_set_option() будет вызываться с параметром STREAM_OPTION_READ_BUFFER. Для пользовательских потоковых обёрток, возможно, потребуется реализация метода streamWrapper::stream_set_option(), чтобы убрать предупреждение (как правило, хватает только возврата false).

Сериализация

Удалён формат сериализации o. Поскольку сам PHP им не пользуется, он мог только нарушить десериализацию строк, созданных вручную.

Константы алгоритма пароля

Идентификаторы алгоритма хеширования паролей теперь обнуляемые строки, а не целые числа.

  • PASSWORD_DEFAULT раньше было целочисленным 1; теперь строка '2y' (в PHP 7.4.0, 7.4.1 и 7.4.2 было null)
  • PASSWORD_BCRYPT раньше было целочисленным 1; теперь строка '2y'
  • PASSWORD_ARGON2I раньше было целочисленным 2; теперь строка 'argon2i'
  • PASSWORD_ARGON2ID раньше было целочисленным 3; теперь строка 'argon2id'

Приложения, правильно использующие константы PASSWORD_DEFAULT, PASSWORD_BCRYPT, PASSWORD_ARGON2I и PASSWORD_ARGON2ID, будут работать как и раньше.

Функция htmlentities()

Функция htmlentities() теперь будет выдавать уведомление (вместо предупреждения уровня E_STRICT), если она используется с кодировкой, для которой поддерживается только преобразование основных символов. В этом случае она эквивалентна использованию htmlspecialchars().

Функции fread() и fwrite()

Функции fread() и fwrite() теперь будут возвращать false, если операция не удалась. Ранее возвращалась пустая строка или 0. К ошибкам EAGAIN/EWOULDBLOCK это не относится.

Эти функции теперь также вызывают уведомление при неудачном выполнении, например, при записи в файловый ресурс, предназначенный только для чтения.

Вычисления над числами с произвольной точностью BCMath

Теперь функции BCMath будут выдавать предупреждения, если передано число с ошибкой, например, "32foo". Подобный аргумент, как и раньше, будет интерпретирован как ноль.

CURL

Попытка сериализации класса CURLFile теперь создаст исключение. Ранее исключение выбрасывалось только при десериализации.

Использование CURLPIPE_HTTP1 объявлено устаревшим, и не будет поддерживаться с версии cURL 7.62.0.

Параметр $version функции curl_version() объявлен устаревшим. Если передаётся значение, не равное CURLVERSION_NOW по умолчанию, будет вызвано предупреждение, а параметр проигнорирован.

Дата и время

Вызов var_dump() или похожей отладочной функции с экземпляром DateTime или DateTimeImmutable больше не оставляет после своего выполнения доступных свойств.

Сравнение объектов DateInterval (с использованием ==, < и т.д.) теперь создаёт предупреждение и всегда возвращает false. Ранее все объекты DateInterval считались одинаковыми, если у них не было свойств.

Intl

Значение параметров по умолчанию в функциях idn_to_ascii() и idn_to_utf8() теперь INTL_IDNA_VARIANT_UTS46 вместо устаревшего INTL_IDNA_VARIANT_2003.

MySQLi

Функциональность встроенного сервера была удалена. Она была сломана как минимум с PHP 7.0.

Недокументированное свойство mysqli::$stat было удалено в пользу использования mysqli::stat().

OpenSSL

Функция openssl_random_pseudo_bytes() теперь будет выбрасывать исключение в тех же ситуациях, что и функция random_bytes(). В частности, выбрасывается исключение Error, если количество запрошенных байтов меньше или равно нулю. Исключение Exception выбрасывается, если не получена достаточная случайность. Аргумент $crypto_strong гарантированно будет равен true, если функция ничего не выбрасывает, поэтому явно проверять его не нужно.

Регулярные выражения (совместимые Perl)

При использовании флага PREG_UNMATCHED_AS_NULL, завершающие несовпадающие подмаски теперь будут иметь значение null (или [null, -1], если включено сохранение позиции подмаски). Это означает, что размер $matches всегда будет одинаковым.

Объекты данных PHP (PDO)

Попытка сериализовать экземпляр PDO или PDOStatement теперь создаст Exception, а не PDOException, по аналогии с другими внутренними классами, которые не поддерживают сериализацию.

Reflection

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

Изменились значения констант классов ReflectionClassConstant, ReflectionMethod и ReflectionProperty.

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

Вызов get_object_vars() с экземпляром ArrayObject теперь всегда будет возвращать свойства самого ArrayObject (или подкласса). Ранее он возвращал значения упакованного массива/объекта, если не был указан флаг ArrayObject::STD_PROP_LIST.

Другие затронутые операции:

  • ReflectionObject::getProperties()
  • reset(), current() и т.д. Используйте вместо этого методы Iterator.
  • Вероятно, все остальное работает со свойствами объекта при доступе в виде списка, например, array_walk().

На приведение типа (array) эти изменения не повлияют. Они по-прежнему возвращают либо упакованный массив, либо свойства ArrayObject, в зависимости от того, используется ли флаг ArrayObject::STD_PROP_LIST.

Метод SplPriorityQueue::setExtractFlags() выбросит исключение, если передан ноль. Ранее это приводило к отлавливаемой фатальной ошибке при следующей операции извлечения.

ArrayObject, ArrayIterator, SplDoublyLinkedList и SplObjectStorage теперь поддерживают __serialize() и __unserialize() в дополнение к интерфейсу Serializable. Поэтому теперь созданные в более старых версиях PHP сериализованные данные, всё ещё могут быть неверно обработаны. Однако новые созданные сериализованные данные в PHP 7.4, не будут восприниматься в более старых версиях.

Лексер (Tokenizer)

Функция token_get_all() теперь отобразит метку T_BAD_CHARACTER в случае обнаружения непредвиденных символов в потоке меток.

Входящие Cookies

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

Добавить

Примечания пользователей 1 note

up
18
happydog at kennel17
3 years ago
Re: "The o serialization format has been removed. As it is never produced by PHP, this may only break unserialization of manually crafted strings."

This little-o serialisation format was used by PHP3 but was never generated by PH PHP4 or above. The deserialization code still recognised it, though, for reasons of backwards-compatibility with PHP3.

However, based on a bit of investigation, it looks like this code has been broken for about 15 years, so although this is listed as a deprecation, in practice it wasn't.

See this Stack Overflow question for a really great answer, with a lot more detail about this: https://stackoverflow.com/questions/65289729/what-was-phps-o-serialization-format-for
To Top