set_error_handler(callable $callback, int $error_levels = E_ALL): ?callable
Расскажите об этой функции всё, что знаете.
set_error_handler()
— мощный инструмент для кастомной обработки не-фатальных ошибок PHP. Она позволяет:
- Логировать ошибки в нужном формате
- Преобразовывать ошибки в исключения
- Гибко настраивать отображение ошибок для разных окружений
- Создавать единую систему обработки ошибок в приложении
Полный ответ:
1. Основное назначение и синтаксис
set_error_handler()
— это функция для установки пользовательского обработчика ошибок. Она перехватывает ошибки, которые обычно выводятся в лог или отображаются пользователю.
set_error_handler(callable $callback, int $error_levels = E_ALL): ?callable
$callback
— функция-обработчик$error_levels
— маска типов ошибок, которые будет обрабатывать handler (по умолчаниюE_ALL
)- Возвращает предыдущий обработчик или
null
2. Сигнатура функции-обработчика
Обработчик должен принимать 4 обязательных параметра:
function myErrorHandler(
int $errno, // Уровень ошибки (E_ERROR, E_WARNING и т.д.)
string $errstr, // Сообщение об ошибке
string $errfile, // Файл, где произошла ошибка
int $errline // Строка, где произошла ошибка
): bool {
// Возвращает true, если ошибка обработана, false - для передачи встроенному обработчику
return true;
}
3. Типы ошибок, которые можно перехватить
set_error_handler()
перехватывает не-фатальные ошибки:
E_WARNING
— предупрежденияE_NOTICE
— уведомленияE_USER_ERROR
— пользовательские ошибкиE_USER_WARNING
— пользовательские предупрежденияE_USER_NOTICE
— пользовательские уведомленияE_DEPRECATED
— устаревшие функцииE_USER_DEPRECATED
— пользовательские deprecated-уведомления
Не перехватываются:
E_ERROR
— фатальные ошибкиE_PARSE
— ошибки парсингаE_CORE_ERROR
— ошибки ядраE_COMPILE_ERROR
— ошибки компиляции
4. Практические примеры
Базовый обработчик:
set_error_handler(function($errno, $errstr, $errfile, $errline) {
echo "Ошибка [$errno]: $errstr в $errfile на строке $errline";
return true; // Ошибка обработана, стандартный обработчик не вызывается
});
echo $undefinedVar; // Выведет наше сообщение вместо стандартного Notice
Логирование ошибок:
set_error_handler(function($errno, $errstr, $errfile, $errline) {
$message = date('[Y-m-d H:i:s]') . " [$errno] $errstr в $errfile:$errline";
file_put_contents('error.log', $message . PHP_EOL, FILE_APPEND);
// В продакшене не показываем детали пользователю
if (!DEBUG_MODE) {
echo "Произошла ошибка. Мы уже работаем над исправлением.";
}
return true;
});
5. Преобразование ошибок в исключения
Распространенная практика — преобразовывать ошибки в исключения ErrorException
:
set_error_handler(function($errno, $errstr, $errfile, $errline) {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});
try {
echo $undefinedVariable; // Выбросит ErrorException вместо Notice
} catch (ErrorException $e) {
echo "Поймано исключение: " . $e->getMessage();
}
6. Обработка только определенных типов ошибок
Можно указать, какие типы ошибок должен обрабатывать handler:
// Обрабатываем только WARNING и ERROR, но не NOTICE
set_error_handler('myHandler', E_WARNING | E_USER_ERROR);
function myHandler($errno, $errstr, $errfile, $errline) {
// Сюда попадут только WARNING и ERROR
return true;
}
7. Возвращаемое значение обработчика
return true
— ошибка обработана, стандартный обработчик не вызываетсяreturn false
— ошибка передается стандартному обработчику PHP
set_error_handler(function($errno, $errstr, $errfile, $errline) {
if ($errno === E_NOTICE) {
// Игнорируем Notice, передаем остальное стандартному обработчику
return false;
}
// Обрабатываем все остальные типы ошибок
echo "Серьезная ошибка: $errstr";
return true;
});
8. Восстановление и сброс обработчика
Сохраняем предыдущий обработчик:
$previousHandler = set_error_handler('myErrorHandler');
// Восстанавливаем
set_error_handler($previousHandler);
Сброс к стандартному обработчику:
restore_error_handler(); // Восстанавливает предыдущий обработчик
9. Отличие от set_exception_handler()
Критически важное различие:
Аспект | set_error_handler() |
set_exception_handler() |
---|---|---|
Что перехватывает | Ошибки (E_WARNING, E_NOTICE) | Непойманные исключения |
Сигнатура | function($errno, $errstr, $errfile, $errline) |
function(Throwable $exception) |
Фатальные ошибки | Не перехватывает | Перехватывает (кроме parse error) |
10. Практическое применение в проектах
Единый обработчик ошибок:
class ErrorHandler {
public static function handleError($errno, $errstr, $errfile, $errline) {
// Логируем в файл
self::logError($errno, $errstr, $errfile, $errline);
// В режиме разработки показываем подробности
if (APP_ENV === 'development') {
self::displayError($errno, $errstr, $errfile, $errline);
}
return true;
}
private static function logError($errno, $errstr, $errfile, $errline) {
$message = "[$errno] $errstr in $errfile:$errline";
error_log($message);
}
}
set_error_handler(['ErrorHandler', 'handleError']);
Комбинированная обработка ошибок и исключений:
// Преобразуем ошибки в исключения
set_error_handler(function($errno, $errstr, $errfile, $errline) {
throw new ErrorException($errstr, 0, $errno, $errfile, $errline);
});
// Обрабатываем все непойманные исключения
set_exception_handler(function($exception) {
error_log("Uncaught exception: " . $exception->getMessage());
http_response_code(500);
echo "Internal Server Error";
});
11. Ограничения и особенности
- Не перехватывает фатальные ошибки — для них нужен
register_shutdown_function()
- @-оператор подавляет ошибки до вызова обработчика
- Не влияет на error_reporting() — только на отображение/логирование
Итог:
set_error_handler()
— мощный инструмент для кастомной обработки не-фатальных ошибок PHP. Она позволяет:
- Логировать ошибки в нужном формате
- Преобразовывать ошибки в исключения
- Гибко настраивать отображение ошибок для разных окружений
- Создавать единую систему обработки ошибок в приложении
Критически важно понимать разницу между обработкой ошибок и исключений, а также помнить о невозможности перехвата фатальных ошибок через этот механизм.