-
match
теперь зарезервированное ключевое слово.
-
mixed
теперь зарезервированное слово, поэтому его нельзя использовать для названия класса, интерфейса или черты, а также запрещено использовать в пространствах имён.
-
Ошибки утверждений (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 false;
}
// ...
}
// На это
function my_error_handler($err_no, $err_msg, $filename, $linenum) {
if (!(error_reporting() & $err_no)) {
return false;
}
// ...
}
?>
Кроме этого, обязательно следует скрыть отображение сообщений об ошибках в производственной среде,
которые могут привести к утечке информации. Проверьте, что 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.
-
Попытка получить доступ к неквалифицированным константам, которые не определены.
Ранее неквалифицированный доступ к константам приводил к предупреждению и интерпретировался как строка.
-
Передача неверного количества аргументов в невариативную встроенную функцию приведёт
к ошибке ArgumentCountError.
Ряд уведомлений преобразован в предупреждения:
- Попытка прочитать неопределённую переменную.
- Попытка прочитать неопределённое свойство.
- Попытка прочитать неопределённый ключ массива.
- Попытка прочитать свойство не-объекта.
- Попытка получить доступ к индексу массива не-массива.
- Попытка преобразовать массив в строку.
- Попытка использовать ресурс в качестве ключа массива.
- Попытка использовать 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 FirstInterface, SecondInterface {};
// -> FirstInterface@anonymous
new class {};
// -> class@anonymous
?>
За новыми именами по-прежнему будет следовать NUL-байт и уникальный суффикс.
-
Ссылки на неабсолютные трейты методов в адаптациях псевдонимов трейтов теперь должны быть
однозначными:
<?php
class X {
use T1, T2 {
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() подвергается специальной обработке со стороны движка,
что может привести к несогласованному поведению при определении одноимённой функции в пространстве имён.