PHP 7.2.0 Release Candidate 4 Released

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

Вызов исключения при передаче функции недостаточного количества аргументов

Ранее, если пользовательская функция вызывалась с недостаточным количеством аргументов, выдавалось предупреждение. Теперь же, вместо предупреждения будет вызываться исключение класса Error. Это изменение затрагивает только пользовательские функции и не оказывает влияния на встроенные. Например:

<?php
function test($param){}
test();

Результатом выполнения данного примера будет что-то подобное:

Fatal error: Uncaught ArgumentCountError: Too few arguments to function test(), 0 passed in %s on line %d and exactly 1 expected in %s:%d

Запрет динамического вызова функций интроспекции области видимости

Динамические вызовы определенных функций были запрещены (в виде $func() или array_map('extract', ...), и т.д.) Эти функции проверяют или модифицируют объекты другой области видимости, чем вызывают неоднозначное и неопределенное поведение. Список таких функций:

<?php
(function () {
    
$func 'func_num_args';
    
$func();
})();

Результат выполнения данного примера:

Warning: Cannot call func_num_args() dynamically in %s on line %d

Некорректные имена классов, интерфейсов и трейтов

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

  • void
  • iterable

Преобразование числовых строк теперь учитывает научную нотацию

Целочисленные операции и конвертации числовых строк теперь учитывают научную нотацию, включая приведение (int) и следующие функции: intval() (с базой 10), settype(), decbin(), decoct(), и dechex().

Исправление алгоритма mt_rand()

mt_rand() теперь по умолчанию использует зафиксированную версию алгоритма "Вихрь Мерсена". Если вы полагались на детерминированный вывод mt_srand(), для сохранения старого (неправильного) поведения, можно использовать константу MT_RAND_PHP в качестве второго, необязательного, параметра mt_srand().

rand() псевдоним для mt_rand() и srand() псевдоним для mt_srand()

rand() и srand() теперь являются просто синонимами для mt_rand() и mt_srand(). Это означает, что вывод следующих функций изменится: rand(), shuffle(), str_shuffle(), и array_rand().

Запрет использовать символ удаления из таблицы ASCII в идентификаторах

Символ удаления ASCII (0x7F) больше нельзя использовать в идентификаторах, не обернутых в кавычки.

Значение error_log изменено на syslog

Если ini-параметр error_log установлен как syslog, то уровни ошибок PHP проецируются на уровни ошибок "syslog". Это позволяет более тонко логировать события, а не как раньше, когда они все записывались с уровнем "notice".

Деструкторы не вызываются на незавершенных объектах

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

call_user_func() обрабатывает ссылки на аргументы

Теперь, call_user_func() всегда вызывает предупреждение, если вызывается функция, ожидающая ссылки в качестве параметров. Ранее это зависело от того, был ли вызов полностью определенным.

Дополнительно, call_user_func() и call_user_func_array() больше не прекращают выполнение функции в этом случае. Предупреждение "expected reference" будет вызвано, но сама функция продолжит выполнение.

Оператор пустого индекса более не применим к строкам

Применение оператора пустого индекса к строке ($str[] = $x) вызывает фатальную ошибку, вместо тихого преобразование переменной к массиву.

Удаленные ini-директивы

Следующие ini-директивы были удалены:

  • session.entropy_file
  • session.entropy_length
  • session.hash_function
  • session.hash_bits_per_character

Порядок массива, когда элементы созданы автоматически через присвоение по ссылке, был изменен

Порядок расположения элементов массива, создаваемых присвоением по ссылке не созданных на момент присвоения элементов, был изменен. К примеру:

<?php
$array 
= [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
?>

Результат выполнения данного примера в PHP 7.0:

array(2) {
  ["a"]=>
  &int(1)
  ["b"]=>
  &int(1)
}

Результат выполнения данного примера в PHP 7.1:

array(2) {
  ["b"]=>
  &int(1)
  ["a"]=>
  &int(1)
}

Порядок сортировки эквивалентных элементов

Внутренний алгоритм сортировки был улучшен, что может привести к отличию в порядке расположения эквивалентных элементов после сортировки по сравнению с предыдущими версиями PHP.

Замечание:

Не полагайтесь на порядок расположения эквивалентных элементов, так как он может в любой момент измениться.

Сообщения для ошибок E_RECOVERABLE

Сообщения для ошибок E_RECOVERABLE изменено с "Catchable fatal error" на "Recoverable fatal error".

Параметр $options функции unserialize()

Теперь элемент allowed_classes параметра $options функции unserialize() строго типизирован, т.е если передать значение с типом отличным от array и boolean, то unserialize() вернет FALSE и вызовет ошибку уровня E_WARNING.

Конструктор DateTime использует микросекунды

Теперь DateTime и DateTimeImmutable используют микросекунды при инстанцировании текущим временем, либо в явном виде, либо со строкой относительного времени (например "first day of next month"). Это означает, что сравнение двух подряд созданных экземпляров класса скорее будет возвращать FALSE нежели TRUE:

<?php
new DateTime() == new DateTime();
?>

Вызов исключений Error вместо фатальных ошибок

Для расширения Date, некорректные данные сериализации классов DateTime или DatePeriod, или ошибка инициализации временной зоны из сериализованных данных, будет выбрасываться исключение Error из методов __wakeup() или __set_state(), вместо вызова фатальной ошибки.

В расширении DBA, функции манипулирования данными (такие как dba_insert()) теперь будут выбрасывать исключение Error вместо вызова отлавливаемой фатальной ошибки если ключ не содержит ровно двух элементов.

В расширении DOM, некорректная проверка контекста схемы или RelaxNG теперь будут выбрасывать исключение Error вместо вызова фатальной ошибки. Также, попытки зарегистрировать класс узла, который не расширяет правильный базовый класс, попытки прочитать некорректное свойство или перезаписать свойство доступное только для чтения будут выбрасывать исключение Error.

В расширение IMAP, адрес email длинее 16385 байт теперь будет выбрасывать исключение Error вместо вызова фатальной ошибки.

Расширение Intl extension, при ошибке вызова родительского конструктора в классе, наследующем Collator до вызова родительских методов теперь будет выбрасывать исключение Error вместо вызова фатальной ошибки. Также, клонирование объекта Transliterator теперь будет выбрасывать исключение Error при ошибке клонирования внутреннего transliterator вместо вызова фатальной ошибки.

Расширение LDAP, при указании неизвестного типа модификации в ldap_batch_modify() теперь будет выбрасывать исключение Error вместо вызова фатальной ошибки.

В расширении mbstring, функции mb_ereg() и mb_eregi() теперь будут выбрасывать исключение ParseError в случае некорректного регулярного выражения либо в случае использования опции 'e'.

В расширении Mcrypt, mcrypt_encrypt() и mcrypt_decrypt() теперь будет выбрасывать исключение Error вместо вызова фатальной ошибки, если mcrypt не инициализирован.

В расширении mysqli, попытки прочитать некорректное свойство или перезаписать свойство доступное только для чтения будут выбрасывать исключение Error вместо вызова фатальной ошибки.

В расширении Reflection, неудачное извлечение отраженного объекта или свойства объекта будут выбрасывать исключение Error вместо вызова фатальной ошибки.

В расширении Session, самописные обработчики сессии, которые не возвращают строку для идентификатора сессии будут выбрасывать исключение Error вместо вызова фатальной ошибки, когда будет вызвана функция для генерации идентификатора.

В расширении SimpleXML, попытка создания безымянного либо дублирующего аттрибута будет выбрасывать исключение Error вместо вызова фатальной ошибки.

В расширении SPL, попытка клонировать объект SplDirectory будет выбрасывать исключение Error вместо вызова фатальной ошибки. Аналогично, вызов ArrayIterator::append() когда итерация объекта закончена будет выбрасывать исключение Error.

Функция assert(), когда ей передан строковый аргумент первым параметром, теперь будет выбрасывать исключение ParseError вместо вызова отлавливаемой фатальной ошибки, если PHP код некорректен. Аналогично, вызов forward_static_call() за пределами пространства класса будет выбрасывать исключение Error.

В расширении Tidy, ручное создание tidyNode будет выбрасывать исключение Error.

В расширении WDDX, зацикленные ссылки при сериализации будут выбрасывать исключение Error вместо вызова фатальной ошибки.

В расширении XML-RPC, зацикленные ссылки при сериализации будут выбрасывать исключение Error вместо вызова фатальной ошибки.

В расширении Zip, метод ZipArchive::addGlob() зацикленные ссылки при сериализации будет выбрасывать исключение Error вместо вызова фатальной ошибки если отсутствует поддержка glob.

Лексически связанные переменные не могут переиспользовать имена

Переменные привязанные к замыканию через конструкцию use, не могут использовать те же имена, что и любые superglobals, $this или параметры. К примеру, все приведенные функции вызовут фатальную ошибку:

<?php
$f 
= function () use ($_SERVER) {};
$f = function () use ($this) {};
$f = function ($param) use ($param) {};

Изменен тип параметра long2ip()

Теперь long2ip()() ожидает параметр типа int а не string.

Кодирование и декодирование JSON

INI-настройка serialize_precision определяет точность сериализации при кодировании значений типа float.

Теперь декодирование пустого ключа приводит к появлению свойства с пустым именем, раньше имя свойства приводилось к значению _empty_.

<?php
var_dump
(json_decode(json_encode(['' => 1])));

Результатом выполнения данного примера будет что-то подобное:

object(stdClass)#1 (1) {
  [""]=>
  int(1)
}

При передаче флага JSON_UNESCAPED_UNICODE в функцию json_encode(), последовательности U+2028 и U+2029 будут экранированы.

Изменение в семантике параметров mb_ereg() и mb_eregi()

Третий параметр функций mb_ereg() и mb_eregi() (regs) теперь устанавливается равным пустому массиву, если небыло найдено совпадений. Ранее, в таких случаях, он оставался неизменным.

Удалена поддержка потока sslv2

Поддержка потока sslv2 в OpenSSL удалена.

add a note add a note

User Contributed Notes 3 notes

up
25
love at sickpeople dot se
10 months ago
For anyone migrating from 5.x to 7.1:

About "Array ordering when elements are automatically created during by reference assignments has changed" on this page

(http://php.net/manual/en/migration71.incompatible.php#migration71.incompatible.array-order)

The behaviour of 7.1 is THE SAME as of PHP 5. It is only 7.0 that differs.

See https://3v4l.org/frbUc

<?php

$array
= [];
$array["a"] =& $array["b"];
$array["b"] = 1;
var_dump($array);
up
9
kees at twekaers dot net
6 months ago
The backwards incompatible change 'The empty index operator is not supported for strings anymore' has a lot more implications than just a fatal error on the following code

<?php
$a
= "";
$a[] = "hello world";
var_dump($a);
?>

This will give a fatal error in 7.1 but will work as expected in 7.0 or below and give you: (no notice, no warning)

array(1) {
  [0]=>
  string(11) "hello world"
}

However, the following is also changed:

<?php
$a
= "";
$a[0] = "hello world";
var_dump($a);
// 7.1: string(1) "h"
// pre-7.1: array(1) {  [0]=>  string(11) "hello world" }

$a = "";
$a[5] = "hello world";
var_dump($a);
// 7.1: string(6) "     h"
// pre-7.1: array(1) {  [0]=>  string(11) "hello world" }

?>
up
7
m dot r dot sopacua at gmail dot com
9 months ago
"OMFG! Why was session.hash_function removed?!? Dude!"

https://wiki.php.net/rfc/session-id-without-hashing

There. Saved ya a search.
To Top