У PHP 8.5 з'явилося нове налаштування fatal_error_backtraces
, яке контролює, чи буде показано трасування викликів для фатальних помилок. У стабільних версіях PHP на сьогодні, наприклад, у PHP 8.4, фатальні помилки без трасування можуть виникати через синтаксичні помилки (наприклад, парсинг), дублювання функцій чи класів, а також безкінечні цикли з обмеженням часу виконання тощо.
На прикладі розглянемо скрипт, що містить дубльовані класи:
class A {
public function loadClassB() {
require 'b.php';
return new B();
}
}
class B {}
class C {
public function loadClassA() {
return new A();
}
}
(new C())->loadClassA()->loadClassB();
При цьому b.php
також визначає клас B
:
// b.php
class B {};
Якщо ви запустите цей код у PHP 8.4 або ранніших версіях, отримаєте таке повідомлення:
Фатальна помилка: Не можна оголосити клас B, оскільки ім'я вже використовується
у /srv/app/b.php на рядку 3
Починаючи з PHP 8.5, ви отримаєте набагато кориснішу інформацію, що пояснює причину фатальної помилки. Хоча в даному простому прикладі без загальної трасування зрозуміло, що насправді в типовій програмі доступ до трасування викликів значно полегшить виправлення помилок:
Фатальна помилка: Не можна переназначити клас B (раніше оголошено в /srv/app/index.php:11) у /srv/app/b.php на рядку 3
Трасування викликів:
#0 /srv/app/index.php(6): require()
#1 /srv/app/index.php(21): A->loadClassB()
#2 {main}
За замовчуванням, значення налаштування INI - fatal_error_backtraces=1
в PHP 8.5, тобто функція включена за замовчуванням. Якщо з якоїсь причини ви хочете її вимкнути, можете встановити fatal_error_backtraces=0
:
$ php -d fatal_error_backtraces=0 index.php
Фатальна помилка: Не можна переназначити клас B (раніше оголошено в /srv/app/index.php:11) у /srv/app/b.php на рядку 3
Щоб дізнатися більше про цю функцію, ознайомтеся з прийнятим і реалізованим RFC: rfc:error_backtraces_v2.