Фатальні помилки PHP: Як працюють backtrace у PHP 8.1

Перекладено ШІ
Оригінал: Laravel News
Оновлено: 12 липня, 2025
Чи знаєте ви, як нове налаштування `fatal_error_backtraces` у PHP 8.5 може полегшити пошук помилок у вашому коді? У цій статті ми розглянемо, як це нововведення допомагає поліпшити інформацію про фатальні помилки, що може значно спростити процес налагодження

У 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.