Настройка вывода ошибок PHP: методы и примеры кода

Раздел: Обработка ошибок PHP -> Настройка отображения ошибок

Основы отображения ошибок PHP

Как сделать, чтобы PHP показывал все ошибки?

Наиболее эффективное решение - настройка через основной конфигурационный файл php.ini. Это обеспечивает глобальное включение отображения ошибок для всех скриптов на сервере. Для этого необходимо изменить следующие директивы:

display_errors = On
error_reporting = E_ALL
display_startup_errors = On

Php показать ошибки (отображение ошибок php)

Директива display_errors отвечает за вывод ошибок на экран (в браузер или консоль). error_reporting задает уровень ошибок, которые будут отображаться. Значение E_ALL включает все типы ошибок, включая предупреждения и уведомления. display_startup_errors включает отображение ошибок, возникающих на этапе загрузки PHP (например, при загрузке расширений).

Типичная проблема: после изменения php.ini изменения не применяются.

Решение: необходимо перезапустить веб-сервер (Apache, Nginx) или перезагрузить PHP-FPM. Для проверки текущих настроек можно использовать функцию phpinfo().

Если доступ к php.ini отсутствует (например, на общем хостинге), этот способ недоступен. В таком случае следует рассмотреть альтернативные варианты.

Как настроить отображение ошибок без доступа к php.ini?

Можно использовать функции ini_set() и error_reporting() непосредственно в коде скрипта. Это позволяет включать отображение ошибок для конкретного скрипта или всего проекта (если разместить вызовы в общем файле инициализации).

error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('display_startup_errors', 1);

Рекомендуется размещать этот код в самом начале скрипта перед любым другим кодом. Однако такой подход не отобразит ошибки, возникшие до выполнения этих строк (например, синтаксические ошибки в том же файле). Для решения этой проблемы можно вынести вызовы в отдельный файл (например, bootstrap.php) и подключать его через require во всех скриптах. Но синтаксические ошибки в самом bootstrap также не будут показаны.

Проблема: если в php.ini установлена директива display_errors = Off и она помечена как PHP_INI_SYSTEM (изменяется только в php.ini), то ini_set не сработает и вернет false. Решение: проверить возможность переопределения с помощью ini_get() или использовать .htaccess (если сервер Apache).

Как включить отображение ошибок на сервере Apache через .htaccess?

Если сервер работает под управлением Apache с модулем mod_php, можно настроить отображение ошибок через файл .htaccess в корне сайта. Это не требует доступа к php.ini.

php_flag display_errors on
php_value error_reporting 32767
php_flag display_startup_errors on

Значение 32767 соответствует E_ALL (для PHP 5.4+ можно использовать E_ALL напрямую: php_value error_reporting E_ALL, но не все версии Apache поддерживают константы).

Проблема: директивы могут не работать, если в конфигурации Apache запрещено переопределение (AllowOverride None) или используется режим CGI/FastCGI. В последнем случае следует использовать конфигурационные файлы пулов или php.ini пользователя.

Как создать собственный обработчик ошибок с выводом на экран?

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

function myErrorHandler($severity, $message, $file, $line) {
    if (error_reporting() & $severity) {
        echo "<b>Ошибка:</b> [$severity] $message в файле $file на строке $line<br>";
    }
    return true; // не вызывать стандартный обработчик
}
set_error_handler('myErrorHandler');

Однако такой обработчик не перехватывает фатальные ошибки (E_ERROR, E_PARSE, E_CORE_ERROR). Для их отображения необходимо дополнительно зарегистрировать функцию через register_shutdown_function() и получать последнюю ошибку с помощью error_get_last().

Проблема: при использовании set_error_handler() ошибки могут не выводиться, если в самом обработчике произойдет ошибка. Решение: обернуть код в try-catch или использовать дополнительные проверки.

Как показать ошибки при запуске скрипта из командной строки?

Для CLI-скриптов можно временно включить отображение ошибок через параметры командной строки:

php -d display_errors=1 -d error_reporting=E_ALL script.php

Также можно добавить настройки в php.ini для CLI (обычно отдельный файл php-cli.ini).

Как проверить текущие настройки отображения ошибок?

Создайте скрипт с вызовом phpinfo():

<?php phpinfo(); ?>

Найдите в выводе раздел error_handling или display_errors. Это позволит быстро увидеть активные директивы и понять, какие изменения уже применены.

Дополнительные примеры и расширенные сценарии

Ниже приведены различные примеры настройки отображения ошибок с подробными пояснениями.

Пример 1: Разные уровни error_reporting

Пример
<?php
// Показать все ошибки, кроме уведомлений (NOTICE)
error_reporting(E_ALL & ~E_NOTICE);
ini_set('display_errors', 1);

// Пример кода с ошибками
echo $undefined_var; // Warning
echo 1/0; // Warning
trigger_error('Пользовательская ошибка', E_USER_NOTICE); // Не будет показана
?>
Warning: Undefined variable $undefined_var in /path/to/script.php on line 7
Warning: Division by zero in /path/to/script.php on line 8

Пояснение: уровень E_ALL & ~E_NOTICE исключает уведомления, поэтому E_USER_NOTICE не выводится.

Пример 2: Использование @ для подавления и error_get_last()

Пример
<?php
@$result = 1/0; // Подавление ошибки
$lastError = error_get_last();
if ($lastError !== null) {
    echo 'Последняя ошибка: ', $lastError['message'];
}
?>
Последняя ошибка: Division by zero

Пояснение: оператор @ временно отключает отображение конкретной ошибки, но она всё равно может быть получена через error_get_last(). Однако подавление не рекомендуется, так как затрудняет отладку.

Пример 3: Комбинация display_errors и log_errors для разработки

Пример
<?php
// Включить отображение на экран и запись в лог одновременно
ini_set('display_errors', 1);
ini_set('log_errors', 1);
ini_set('error_log', '/path/to/php_errors.log');
error_reporting(E_ALL);

trigger_error('Тестовая ошибка', E_USER_WARNING);
echo 'Скрипт продолжает работу';
?>
Warning: Тестовая ошибка in /path/to/script.php on line 8
Скрипт продолжает работу

В файле php_errors.log появится запись с той же ошибкой. Такой подход позволяет и видеть ошибки в браузере, и сохранять их для последующего анализа.

Пример 4: Пользовательский обработчик с перехватом фатальных ошибок

Пример
<?php
function customErrorHandler($severity, $message, $file, $line) {
    echo "<b>Ошибка уровня $severity:</b> $message в $file:$line<br>";
    return true;
}
set_error_handler('customErrorHandler');

function shutdownHandler() {
    $error = error_get_last();
    if ($error !== null && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_CORE_WARNING])) {
        echo "<b>Фатальная ошибка:</b> {$error['message']} в {$error['file']}:{$error['line']}<br>";
    }
}
register_shutdown_function('shutdownHandler');

// Фатальная ошибка: вызов несуществующей функции
existingFunction();
?>
Фатальная ошибка: Call to undefined function existingFunction() in /path/to/script.php on line 18

Пояснение: register_shutdown_function позволяет перехватывать ошибки, которые не обрабатываются set_error_handler, и выводить их аналогично.

Пример 5: Настройка отображения ошибок в production (отключение вывода, включение логирования)

Пример
<?php
// В production среде ошибки не должны показываться пользователю
ini_set('display_errors', 0);
ini_set('log_errors', 1);
ini_set('error_log', '/var/log/php_errors.log');
error_reporting(E_ALL & ~E_DEPRECATED & ~E_STRICT);
?>

Пояснение: display_errors выключен, чтобы избежать утечки информации. Все ошибки записываются в лог. Уровень снижен, чтобы игнорировать устаревшие конструкции, которые не критичны.

Пример 6: Конфигурация через .htaccess с разными значениями

Пример
# Включить отображение всех ошибок
php_flag display_errors on
php_value error_reporting E_ALL
php_flag display_startup_errors on

# Альтернативный вариант: показывать только фатальные и предупреждения
# php_value error_reporting E_ERROR | E_WARNING

Пояснение: в .htaccess можно комбинировать флаги. Значение E_ALL можно заменить на числовой эквивалент (32767) для совместимости. Директива display_startup_errors полезна для отладки ошибок загрузки расширений.

Отображение ошибок PHP - comments

En
Php показать ошибки (php)