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

Ядро PHP

Сравнение строк с числами

Нестрогие сравнения чисел и нечисловых строк теперь работают, как преобразование числа в строку с последующим сравнением строк. Сравнение чисел и числовых строк работает, как и раньше. В частности, это означает, что 0 == "not-a-number" теперь выдаст false.

Сравнение До После
0 == "0" true true
0 == "0.0" true true
0 == "foo" true false
0 == "" true false
42 == " 42" true true
42 == "42foo" true false

Другие изменения, ломающие обратную совместимость

  • match теперь зарезервированное ключевое слово.

  • Ошибки утверждений (assertions) теперь выбрасываются по умолчанию. Если предпочтительнее старое поведение, assert.exception=0 можно установить в INI-настройках.

  • Методы с тем же именем, что и класс, больше не интерпретируются как конструкторы. Вместо этого следует использовать метод __construct().

  • Возможность статического вызова нестатических методов удалена. Таким образом, is_callable() завершится ошибкой при проверке нестатического метода с именем класса (необходимо проверять с экземпляром объекта).

  • Приведения типов (real) и (unset) удалены.

  • INI-директива track_errors удалена. Это означает, что php_errormsg больше не актуален. Вместо него можно использовать функцию error_get_last().

  • Возможность определять константы без учета регистра была удалена. Третий аргумент define() больше не может быть true.

  • Возможность указывать автозагрузчик с помощью функции __autoload() была удалена. Вместо этого следует использовать spl_autoload_register().

  • Аргумент errcontext больше не передаётся в пользовательские обработчики ошибок, заданных с помощью set_error_handler().

  • create_function() была удалена. Вместо нее можно использовать анонимные функции.

  • each() была удалена. Вместо нее можно использовать foreach или ArrayIterator.

  • Возможность отвязать this от замыканий, которые были созданы из метода с использованием Closure::fromCallable() или ReflectionMethod::getClosure(), была удалена.

  • Возможность отвязать this от надлежащих замыканий, содержащих использование this, также была удалена.

  • Возможность использования array_key_exists() с объектами была удалена. Вместо этого можно использовать isset() или property_exists().

  • Работа параметра key в функции array_key_exists() теперь приведена в соответствиие с isset() и обычным доступом к массиву. Все типы ключей теперь используют обычное приведение типов, массив/объект к ключе приведет к выбрасыванию TypeError.

  • Любой массив, у которого в качестве первого числового ключа указано число n, будет использовать n+1 для своего следующего неявного ключа, даже если n отрицательно.

  • Уровень error_reporting по умолчанию теперь E_ALL. Ранее он исключал E_NOTICE и E_DEPRECATED.

  • display_startup_errors теперь включен по умолчанию.

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

  • Оператор @ больше не подавляет фатальные ошибки (E_ERROR, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR, E_RECOVERABLE_ERROR, E_PARSE). Обработчики ошибок, которые ожидают, что error_reporting будет иметь значение 0 при использовании оператора @, должны делать такие проверки через битовую маску:

    <?php
    // Замените это
    function my_error_handler($err_no$err_msg$filename$linenum) {
        if (
    error_reporting() == 0) {
            return; 
    // Ошибка проигнорирована
        
    }
        
    // ...
    }

    // На это
    function my_error_handler($err_no$err_msg$filename$linenum) {
        if (!(
    error_reporting() & $err_no)) {
            return; 
    // Ошибка проигнорирована
        
    }
        
    // ...
    }
    ?>

    Кроме этого, обязательно следует скрыть отображение сообщений об ошибках в производственной среде, которые могут привести к утечке информации. Проверьте, что display_errors=Off используется вместе с включенной записью журнала ошибок.

  • #[ больше не интерпретируется как начало комментария, так как этот синтаксис теперь используется для атрибутов.

  • Ошибки наследования из-за несовместимых сигнатур методов (нарушения LSP) теперь всегда вызывают фатальную ошибку. Ранее в некоторых случаях выдавалось предупреждение.

  • Приоритет оператора конкатенации изменился относительно сдвигов битов и сложения, а также вычитания.

    <?php
    echo "Сумма: " $a $b;
    // ранее интерпретировалось как:
    echo ("Сумма: " $a) + $b;
    // сейчас интерпретируется как:
    echo "Сумма:" . ($a $b);
    ?>

  • Аргументы со значением по умолчанию, которые преобразуется в null во время выполнения, больше не будут неявно помечать тип аргумента как nullable. Вместо этого должно использоваться либо явный тип, допускающий значение null, либо явное значение null по умолчанию.

    <?php
    // Замените этот код:
    function test(int $arg CONST_RESOLVING_TO_NULL) {}
    // На этот:
    function test(?int $arg CONST_RESOLVING_TO_NULL) {}
    // На этот (альтернативный вариант):
    function test(int $arg null) {}
    ?>

  • Ряд предупреждений преобразован в исключения Error:

    • Попытка записи в свойство несуществующего объекта. Ранее это неявно создавало объект stdClass в случае null, false и пустых строк.
    • Попытка добавить элемент в массив, для которого уже используется ключ PHP_INT_MAX.
    • Попытка использовать недопустимый тип (массив или объект) в качестве ключа массива или смещения строки.
    • Попытка записать в индекс массива скалярное значение.
    • Попытка распаковать значение, не являющее массивом/Traversable.
    • Попытка получить доступ к неквалифицированным константам, которые не определены. Ранее неквалифицированный доступ к константам приводил к предупреждению и интерпретировался как строка.

    Ряд уведомлений преобразован в предупреждения:

    • Попытка прочитать неопределенную переменную.
    • Попытка прочитать неопределенное свойство.
    • Попытка прочитать неопределенный ключ массива.
    • Попытка прочитать свойство не-объекта.
    • Попытка получить доступ к индексу массива не-массива.
    • Попытка преобразовать массив в строку.
    • Попытка использовать ресурс в качестве ключа массива.
    • Попытка использовать null, логическое значение или число с плавающей запятой в качестве строкового смещения.
    • Попытка прочитать смещение строки за пределами допустимой границы.
    • Попытка присвоить смещению строки пустую строку.

  • При попытке назначить несколько байтов смещению строки теперь будет выдано предупреждение.

  • Неожиданные символы в исходных файлах (например, байты NUL за пределами строк) теперь будут приводить к исключению ParseError вместо предупреждения при компиляции.

  • Неперехваченные исключения теперь проходят процедуру "чистого завершения", это означает, что после неперехваченного исключения будут вызываться деструкторы.

  • Фатальная ошибка времени компиляции "Only variables can be passed by reference" была отложена до времени выполнения и преобразована в исключение Error "Argument cannot be passed by reference".

  • Некоторые уведомления "Only variables can be passed by reference" были преобразованы в исключение "Argument cannot be passed by reference".

  • Сгенерированное имя для анонимных классов изменилось. Теперь он будет включать имя первого родителя или интерфейса:

    <?php
    new class extends ParentClass {};
    // -> ParentClass@anonymous
    new class implements FirstInterfaceSecondInterface {};
    // -> FirstInterface@anonymous
    new class {};
    // -> class@anonymous
    ?>

    За новыми именами по-прежнему будет следовать NUL-байт и уникальный суффикс.

  • Ссылки на неабсолютные трейты методов в адаптациях псевдонимов трейтов теперь должны быть однозначными:

    <?php
    class {
        use 
    T1T2 {
            
    func as otherFunc;
        }
        function 
    func() {}
    }
    ?>

    Если существуют и T1::func(), и T2::func(), этот код ранее принимался без уведомления, и предполагалось, что func ссылается на T1::func. Теперь вместо этого будет выброшена фатальная ошибка: необходимо явно указать T1::func или T2::func.

  • Сигнатура абстрактных методов, определенных в трейтах, теперь проверяется по методу реализующего класса:

    <?php
    trait MyTrait {
        abstract private function 
    neededByTrait(): string;
    }

    class 
    MyClass {
        use 
    MyTrait;

        
    // Ошибка из-за несоответствия типа возвращаемого значения.
        
    private function neededByTrait(): int { return 42; }
    }
    ?>

  • Отключенные функции теперь обрабатываются точно так же, как несуществующие функции. Вызов отключенной функции сообщит, что нет такой функции, это дает возможность переопределить отключенную функцию.

  • Оболочки потока data:// больше не доступны для записи, что соответствует документированному поведению.

  • Арифметические и побитовые операторы +, -, *, /, **, %, <<, >>, &, |, ^, ~, ++, -- теперь будут последовательно выдавать TypeError, когда одним из операндов является массив (array), ресурс (resource) или не перегруженный объект (object). Единственным исключением из этого правила является операция слияния массивов +, которая по-прежнему поддерживается.

  • Приведение с плавающей точкой в строку теперь всегда будет вести себя независимо от локали.

    <?php
    setlocale
    (LC_ALL"de_DE");
    // Ранее:  3,14
    // Теперь: 3.14
    ?>

    Смотрите printf(), number_format() и NumberFormatter() для получения информации о способах настройки форматирования чисел.

  • Удалена поддержка устаревших фигурных скобок для доступа к смещению.

    <?php
    // Вместо:
    $array{0};
    $array{"key"};
    // Используйте:
    $array[0];
    $array["key"];
    ?>

  • Применение модификатора final к закрытому методу теперь приведет к предупреждению, если этот метод не является конструктором.

  • Если в конструкторе объекта используется exit(), то деструктор объекта больше не будет вызываться. Это соответствует поведению, когда конструктор выбрасывает исключение.

  • Имена в пространстве имен больше не могут содержать пробелы: Foo\Bar будет распознаваться как имя в пространстве имен, Foo \ Bar - нет. И наоборот, зарезервированные ключевые слова теперь разрешены в качестве сегментов пространства имен, что также может изменить интерпретацию кода: new\x теперь совпадает с constant('new\x'), но не с new \x().

  • Для вложенных тернарных операторов теперь требуется явное указание скобок.

  • debug_backtrace() и Exception::getTrace() больше не будут предоставлять ссылки на аргументы. Невозможно изменить аргументы функции через трассировку.

  • Обработка числовых строк была изменена, чтобы сделать ее более понятной и менее подверженной ошибкам. Завершающие пробелы теперь разрешены в числовых строках для согласованности с тем, как обрабатываются начальные пробелы. В основном это влияет на:

    • Функцию is_numeric()
    • Сравнение строк со строками
    • Объявления типов
    • Операции увеличения и уменьшения

    Понятие "ведущая числовая строка" в основном было отброшено; случаи, когда это осталось, существуют для облегчения миграции. Строки, которые выдавали E_NOTICE "A non well-formed numeric value encounteredе", теперь будут выдавать E_WARNING "A non-numeric value encountered", а все строки, которые выдавали E_WARNING "A non-numeric value encountered" теперь будет выдавать TypeError. В основном это влияет на:

    • Арифметические операции
    • Побитовые операции

    Это изменение E_WARNING на TypeError также влияет на E_WARNING "Illegal string offset 'string'" для недопустимых смещений строки. Поведение явных приведений к int/float из строк не изменилось.

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

    • __call(string $name, array $arguments): mixed
    • __callStatic(string $name, array $arguments): mixed
    • __clone(): void
    • __debugInfo(): ?array
    • __get(string $name): mixed
    • __invoke(mixed $arguments): mixed
    • __isset(string $name): bool
    • __serialize(): array
    • __set(string $name, mixed $value): void
    • __set_state(array $properties): object
    • __sleep(): array
    • __unserialize(array $data): void
    • __unset(string $name): void
    • __wakeup(): void

  • Ключи массива call_user_func_array() теперь будут интерпретироваться как имена параметров, а не игнорироваться.

  • Объявление функции с именем assert() внутри пространства имен больше не допускается и вызывает E_COMPILE_ERROR. Функция assert() подвергается специальной обработке со стороны движка, что может привести к несогласованному поведению при определении одноименной функции в пространстве имен.

Преобразование ресурсов в объекты

Несколько ресурсов (resource) были преобразованы в объекты (object). Проверки возвращаемого значения с использованием is_resource() следует заменить проверками на false.

COM и .Net (Windows)

Возможность импорта констант без учета регистра из библиотек типов была удалена. Второй аргумент com_load_typelib() больше не может быть false; com.autoregister_casesensitive больше нельзя отключить; Маркеры без учета регистра в com.typelib_file игнорируются.

CURL

CURLOPT_POSTFIELDS больше не принимает объекты как массивы. Чтобы интерпретировать объект как массив, выполните явное приведение (array). То же самое относится и к другим параметрам, принимающим массивы.

Дата и время

Для работы функций mktime() и gmmktime() теперь требуется хотя бы один аргумент. time() может использоваться для получения текущей отметки времени.

DOM

Были удалены нереализованные классы из модуля DOM, которые не имели обработчика и содержали тестовые данные. Эти классы также были удалены в последней версии стандарта DOM:

  • DOMNameList
  • DomImplementationList
  • DOMConfiguration
  • DomError
  • DomErrorHandler
  • DOMImplementationSource
  • DOMLocator
  • DOMUserDataHandler
  • DOMTypeInfo

Enchant

Exif

read_exif_data() была удалена; Вместо нее следует использовать exif_read_data().

Фильтрация данных

  • Флаги FILTER_FLAG_SCHEME_REQUIRED и FILTER_FLAG_HOST_REQUIRED для фильтра FILTER_VALIDATE_URL были удалены. scheme и host необходимы (и всегда были).

  • Типы INPUT_REQUEST и INPUT_SESSION для filter_input() и ей производных были удалены. Они никогда не были реализованы, а попытка их использования всегда приводила к вызову предупреждения.

GD

  • Устаревшие функции image2wbmp() были удалены.

  • Устаревшие функции png2wbmp() и jpeg2wbmp() были удалены.

  • Параметр mode по умолчанию для функции imagecropauto() больше не принимает значение -1. Вместо этого следует использовать IMG_CROP_DEFAULT.

  • В Windows, php_gd2.dll переименован в php_gd.dll.

GMP

gmp_random() была удалена. Вместо нее следует использовать gmp_random_range() или gmp_random_bits().

Iconv

Реализации iconv, которые неправильно устанавливают errno в случае возникновения ошибок, больше не поддерживаются.

IMAP

  • Неиспользуемый аргумент default_host функции imap_headerinfo() был удален.

  • Функция imap_header(), которая является псевдонимом imap_headerinfo(), была удалена.

Функции интернационализации

  • Устаревшая константа INTL_IDNA_VARIANT_2003 удалена.

  • Устаревшая константа Normalizer::NONE удалена.

LDAP

MBString

  • Директива mbstring.func_overload была удалена. Связанные константы MB_OVERLOAD_MAIL, MB_OVERLOAD_STRING и MB_OVERLOAD_REGEX также были удалены. Наконец, записи "func_overload" и "func_overload_list" в mb_get_info() были удалены.

  • mb_parse_str() больше нельзя использовать без передачи массива результатов.

  • Удален ряд устаревших псевдонимов mbregex. В следующем списке указано, какие функции следует использовать вместо них:

  • Модификатор e для mb_ereg_replace() был удален. Вместо него следует использоватьmb_ereg_replace_callback().

  • Аргумент нестрокового шаблона для mb_ereg_replace() теперь будет интерпретироваться как строка вместо кодовой точки ASCII. Предыдущее поведение можно восстановить явным вызовом chr().

  • Аргумент needle для функций mb_strpos(), mb_strrpos(), mb_stripos(), mb_strripos(), mb_strstr(), mb_stristr(), mb_strrchr() и mb_strrichr() теперь может быть пустым.

  • Параметр is_hex, который не использовался для внутренних целей, был удален из mb_decode_numericentity().

  • Устаревшее поведение передачи кодировки в качестве третьего аргумента вместо смещения для функции mb_strrpos() было удалено; вместо этого в качестве четвертого аргумента следует указать явное смещение 0 с кодировкой.

  • Псевдонимы кодировки символов ISO_8859-* были заменены на псевдонимы ISO8859-* для лучшей совместимости с модулем iconv. Псевдонимы mbregex ISO 8859 с подчеркиванием (ISO_8859_* и ISO8859_*) также были удалены.

  • mb_ereg() и mb_eregi() теперь будут возвращать логическое значение true, в случае найденого совпадения. Ранее они возвращали целое число 1, если аргумент matches не был передан, или max(1, strlen($matches[0])), если matches был не пустой.

OCI8

  • Класс OCI-Lob переименован в OCILob, а класс OCI-Collection - в OCICollection для имени совместимость обеспечивается средствами аннотации типа arginfo PHP 8.

  • Некоторые функции псевдонимов объявлены устаревшим.

  • oci_internal_debug() и ее псевдоним ociinternaldebug() были удалены.

ODBC

  • odbc_connect() больше не использует соединения повторно.

  • Неиспользуемый параметр flags функции odbc_exec() был удален.

OpenSSL

  • openssl_seal() и openssl_open() теперь требуют передачи method, так как предыдущее значение по умолчанию "RC4" считается небезопасным.

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

При передаче недопустимых управляющих последовательностей они больше не интерпретируются как литералы. Такое поведение ранее требовало модификатора X, который теперь игнорируется.

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

  • Режим обработки ошибок по умолчанию был изменен с "тихого" (silent) на "исключения" (exceptions). Подробнее смотрите Ошибки и обработка ошибок.

  • Изменились сигнатуры некоторых методов PDO:

    • PDO::query(string $query, ?int $fetchMode = null, mixed ...$fetchModeArgs)
    • PDOStatement::setFetchMode(int $mode, mixed ...$args)

PDO ODBC

Директива php.ini pdo_odbc.db2_instance_name была удалена.

PDO MySQL

PDO::inTransaction() теперь сообщает о фактическом состоянии транзакции подключения, а не о приблизительном от PDO. Если запрос, при условии "неявной фиксации", выполняется, то PDO::inTransaction() впоследствии вернёт false, так как транзакция будет неактивной.

PostgreSQL

  • Устаревший синтаксис pg_connect() с использованием нескольких параметров вместо строки подключения больше не поддерживается.

  • Устаревшие сигнатуры pg_lo_import() и pg_lo_export(), передающие соединение в качестве последнего аргумента, больше не поддерживаются. Вместо этого соединение должно быть передано первым аргументом.

  • pg_fetch_all() теперь будет возвращать пустой массив вместо false для наборов результатов с отсутствующими строками.

Phar

Метаданные, связанные с phar, больше не будут автоматически десериализоваться, чтобы исправить потенциальные уязвимости безопасности из-за создания экземпляров объекта, автозагрузки и т.д.

Reflection

  • Сигнатуры методов

    • ReflectionClass::newInstance($args)
    • ReflectionFunction::invoke($args)
    • ReflectionMethod::invoke($object, $args)

    были изменены на:

    • ReflectionClass::newInstance(...$args)
    • ReflectionFunction::invoke(...$args)
    • ReflectionMethod::invoke($object, ...$args)

    Код, который должен быть совместим как с PHP 7, так и с PHP 8, может использовать следующие сигнатуры:

    • ReflectionClass::newInstance($arg = null, ...$args)
    • ReflectionFunction::invoke($arg = null, ...$args)
    • ReflectionMethod::invoke($object, $arg = null, ...$args)

  • Метод ReflectionType::__toString() теперь будет возвращать полное отладочное представление типа и больше не является устаревшим. В частности, результат будет включать индикатор допустимости значений NULL для типов, допускающих значение NULL. Формат возвращаемого значения нестабилен и может меняться в зависимости от версии PHP.

  • Методы Reflection export() были удалены. Вместо этого объекты reflection могут быть преобразованы в строку.

  • ReflectionMethod::isConstructor() и ReflectionMethod::isDestructor() теперь также возвращают true для методов интерфейсов __construct() и __destruct(). Раньше это было верно только для методов классов и трейтов.

  • Метод ReflectionType::isBuiltin() перемещен в ReflectionNamedType. У ReflectionUnionType этого метода нет.

Сокеты

  • Устаревшие flags AI_IDN_ALLOW_UNASSIGNED и AI_IDN_USE_STD3_ASCII_RULES для socket_addrinfo_lookup() были удалены.

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

Библиотека стандартных функций

  • assert() больше не будет выполнять строковые аргументы, вместо этого они будут обрабатываться как любые обычные аргументы. Таким образом, вместо assert('$a == $b') следует использовать assert($a == $b). INI-директива assert.quiet_eval и константа ASSERT_QUIET_EVAL были удалены, так как они больше не имеют смысла.

  • parse_str() больше нельзя использовать без указания массива результатов.

  • Фильтр string.strip_tags удален.

  • Аргумент needle функций strpos(), strrpos(), stripos(), strripos(), strstr(), strchr(), strrchr() и stristr() теперь всегда будет интерпретироваться как строка. Раньше нестрочные needles интерпретировались как кодовая точка ASCII. Явный вызов chr() может использоваться для восстановления предыдущего поведения.

  • Аргумент needle функций strpos(), strrpos(), stripos(), strripos(), strstr(), stristr() и strrchr() теперь может быть пустым.

  • Аргумент length функций substr(), substr_count(), substr_compare() и iconv_substr() теперь может быть null. Значения null означает отсутствие аргумента длины, и поэтому функциии вернут остаток строки вместо пустой строки.

  • Аргумент length функции array_splice() теперь может быть null. Передача значения null означает отсутствие аргумента, поэтому функция удалить все, начиная от offset до конца массива.

  • Аргумент args функций vsprintf(), vfprintf() и vprintf() теперь должен быть массивом. Раньше принимался любой тип.

  • Параметр 'salt' функции password_hash() больше не поддерживается. Если используется опция 'salt', генерируется предупреждение, переданная соль игнорируется, а вместо нее используется сгенерированная соль.

  • Функция quotemeta() теперь будет возвращать пустую строку, если была передана пустая строка. Ранее возвращалось false.

  • Удалены следующие функции:

  • FILTER_SANITIZE_MAGIC_QUOTES удалена.

  • Вызов implode() с параметрами в обратном порядке ($pieces, $glue) больше не поддерживается.

  • parse_url() теперь будет различать отсутствующие и пустые запросы и фрагменты:

    • http://example.com/foo → query = null, fragment = null
    • http://example.com/foo? → query = "", fragment = null
    • http://example.com/foo# → query = null, fragment = ""
    • http://example.com/foo?# → query = "", fragment = ""
    Ранее во всех случаях query и fragment были null.

  • var_dump() и debug_zval_dump() теперь будут печатать числа с плавающей запятой, используя serialize_precision, а не precision. В конфигурации по умолчанию это означает, что числа с плавающей запятой теперь печатаются с полной точностью этими функциями отладки.

  • Если массив, возвращаемый __sleep(), содержит несуществующие свойства, теперь они автоматически проигнорируются. Ранее такие свойства были бы сериализованы, как если бы они имели значение null.

  • Локаль по умолчанию при запуске теперь всегда будет определена как "C". По умолчанию локали не наследуются из окружения. Ранее для LC_ALL было задано значение "C", в то время как LC_CTYPE наследовался от окружения. Однако некоторые функции не учитывали унаследованную локаль без явного вызова setlocale(). Явный вызов setlocale() теперь требуется всегда, если компонент локали должен быть изменен с значения по умолчанию.

  • Устаревший резервный вариант DES в crypt() был удален. Если в crypt() передается неизвестный формат соли, функция завершится ошибкой с *0 вместо возврата к слабому хешу DES.

  • При указании значений вне допустимого диапазона для SHA256/SHA512 crypt() теперь будет выдана ошибка *0 вместо ограничения до ближайшего предела. Это соответствует поведению glibc.

  • Результат функций сортировки мог измениться, если в массиве есть одинаковые элементы.

  • Любые функции, принимающие callback-функции, которые явно не указаны для приема параметров по ссылке, теперь будут предупреждать, если используется callback-функция со ссылочными параметрами. Например, array_filter() и array_reduce(). Ранее так было у большинства функций, но не у всех.

  • Обертка HTTP-потока, используемая такими функциями, как file_get_contents(), теперь по умолчанию объявляет HTTP/1.1, а не HTTP/1.0. Это не меняет поведения клиента, но может заставить серверы реагировать по-другому. Чтобы сохранить старое поведение, установите параметр контекста потока 'protocol_version', например:

    <?php
    $ctx 
    stream_context_create(['http' => ['protocol_version' => '1.0']]);
    echo 
    file_get_contents('http://example.org'false$ctx);
    ?>

  • Вызов crypt() без явной передачи соли больше не поддерживается. Если вы хотите создать надежный хеш с автоматически сгенерированной солью, используйте вместо этого password_hash().

  • substr(), mb_substr(), iconv_substr() и grapheme_substr() теперь последовательно фиксируют смещения за пределы границы строки. Ранее, в некоторых случаях, вместо пустой строки возвращался false.

  • В Windows функции выполнения программ (proc_open(), exec(), popen() и т.д.) с использованием оболочки теперь последовательно выполняют %comspec% /s /c "$commandline", которая делеает то же самое, что и выполнение $commandline (без дополнительных кавычек).

Sysvsem

  • Параметр auto_release в sem_get() был изменен, чтобы принимать логические значения (bool), а не целые числа (int).

Tidy

PHP-лексер (Tokenizer)

  • В лексемах T_COMMENT больше не будет символа новой строки в конце. Вместо этого новая строка будет частью следующей лексемы T_WHITESPACE. Следует отметить, что за T_COMMENT не всегда следует пробел, за ним также может быть T_CLOSE_TAG или конец файла.

  • Имена в пространствах имен теперь представлены с помощью T_NAME_QUALIFIED (Foo\Bar), T_NAME_FULLY_QUALIFIED (\Foo\Bar) и лексемы T_NAME_RELATIVE (namespace\Foo\Bar)). T_NS_SEPARATOR используется только для автономных разделителей пространства имен и только синтаксически действителен в сочетании с объявлениями группового использования.

XMLReader

XMLReader::open() и XMLReader::xml() теперь являются статическими методами. Их по-прежнему можно вызывать как методы экземпляра, но наследующие классы должны объявлять их как статические, если они переопределяют эти методы.

XML-RPC

Модуль XML-RPC был перемещен в PECL и больше не является частью дистрибутива PHP.

Zip

ZipArchive::OPSYS_Z_CPM была удалена (в этом имени была опечатка). Используйте вместо нее ZipArchive::OPSYS_CPM.

Zlib

Пакеты тестов PHP для Windows

Скрипт выполнения тестов был переименован из run-test.php в run-tests.php, чтобы соответствовать его имени в php-src.