class HandlerManager
{
public function register()
{
set_exception_handler([$this, 'exception']);
set_error_handler([$this, 'error']);
register_shutdown_function([$this, 'shutdown']);
}
private function log($error, $code, $file, $line)
{
$error = sprintf('Error %s in file %s[%d]: %s', $code, $file, $line, $error);
return error_log($error);
}
public function exception(\Throwable $e)
{
$this->log($e->getMessage(), $e->getCode(), $e->getFile(), $e->getLine());
// clean the output buffer if one exists
ob_get_level() && ob_clean();
header('Content-Type: text/plain; charset=utf-8', true, 500);
echo $e->getMessage();
exit(1);
}
public function error($severity, $error, $file = '', $line = 0)
{
if (error_reporting() & $severity) {
$this->log($error, $severity, $file, $line);
throw new \ErrorException($error, $severity, $file, $line);
}
// dont execute the PHP error handler
return true;
}
public function shutdown(array $shutdown_errors = [E_PARSE, E_ERROR, E_USER_ERROR])
{
$error = error_get_last();
if ($error && in_array($error['type'], $shutdown_errors)) {
// сlean the output buffer
ob_get_level() && ob_clean();
$this->log($error['message'], $error['type'], $error['file'], $error['line']);
// shutdown now to avoid a "death loop"
exit(1);
}
}
}
Вот простой пример класса с обработчиками. Под http ошибки 400-500 лучше завести отдельное исключение(а лучше для каждого кода) + базовое исключение приложения.