Search by

ugeek / php-errors

ugeek

重写PHP错误处理程序,捕获所有PHP运行时错误并支持通过设置日志器将错误日志记录到日志中。

Package info

github.com/tomorrowxxy/php-errors

pkg:composer/ugeek/php-errors

Statistics

Installs: 31

Dependents: 0

Suggesters: 0

Stars: 0

Open Issues: 0

v1.0.0 2026-10-25 16:15 UTC

This package is not auto-updated.

Last update: 2026-11-09 14:46:02 UTC


README

轻量的 PHP 错误处理组件:接管 PHP 的错误、未捕获异常和致命错误,按错误类型映射为 PSR-3 日志级别,交给日志记录器统一记录。

  • 捕获运行时错误(warning、notice、deprecated 等)、未捕获的异常 / Error,以及脚本终止时的致命错误
  • 支持任意 PSR-3 日志记录器(如 Monolog);未设置时回退到 PHP 的 error_log
  • 可按错误报告级别过滤需要记录的错误
  • 开发环境下可将错误直接输出到终端 / 页面

环境要求

  • PHP >= 8.5
  • psr/log ^1.1 || ^2.0 || ^3.0

安装

composer require ugeek/php-errors

推荐同时安装一个 PSR-3 日志库,例如 Monolog(支持 2.x、3.x):

composer require monolog/monolog

快速开始

在应用入口尽早启用:

require __DIR__ . '/vendor/autoload.php';

use Monolog\Handler\StreamHandler;
use Monolog\Logger;
use PHPErrors\PHPErrors;

$logger = new Logger('app');
$logger->pushHandler(new StreamHandler(__DIR__ . '/logs/error.log'));

PHPErrors::enable(E_ALL)->setLogger($logger);

开发环境下想同时在终端 / 页面看到错误,把第二个参数设为 true:

PHPErrors::enable(E_ALL, true);

API

PHPErrors::enable(?int $errorReportLevel = E_ALL, bool $displayErrors = false): static

一步完成配置和注册,返回处理器实例:

  • 设置 error_reporting() 和 PHPErrors::$errorReportLevel 为 $errorReportLevel,传 null 时视为 E_ALL
  • 开启 log_errors
  • 注册错误处理器、异常处理器和 shutdown 函数

只记录部分错误时,可传入位运算组合,例如忽略 deprecated:

PHPErrors::enable(E_ALL & ~E_DEPRECATED & ~E_USER_DEPRECATED);

setLogger(LoggerInterface $logger): static

设置 PSR-3 日志记录器,返回实例本身,可链式调用。

手动注册

不想让组件修改 error_reporting 和 log_errors 时,可以只注册处理器:

$handler = (new PHPErrors(displayErrors: false))->register();
$handler->setLogger($logger);

日志级别映射

PHP 错误类型 PSR-3 日志级别
E_PARSE、E_COMPILE_ERROR alert
E_ERROR、E_CORE_ERROR、未捕获的异常 / Error critical
E_USER_ERROR、E_RECOVERABLE_ERROR error
E_WARNING、E_CORE_WARNING、E_COMPILE_WARNING、E_USER_WARNING warning
E_NOTICE、E_USER_NOTICE、E_DEPRECATED、E_USER_DEPRECATED notice
其他 emergency

未捕获的 ErrorException 按其 getSeverity() 映射。

日志格式

普通错误和致命错误:

/path/to/file.php#12: Undefined variable $foo

未捕获的异常,带异常类名和调用栈:

/path/to/file.php#8: RuntimeException: boom
#0 /path/to/file.php(9): f()
#1 {main}

未设置日志记录器时,会以 {level}: {message} 的格式写入 error_log。

注意事项

  • @ 抑制的错误同样会被记录,这是有意为之,确保不遗漏任何错误。
  • 未捕获的异常被记录后脚本仍会终止,业务异常应在应用代码中通过 try/catch 自行处理。
  • 致命错误(如内存耗尽)无法被 set_error_handler 拦截,组件会在脚本结束时通过 error_get_last() 记录,这类日志不含调用栈。
  • displayErrors 在非 CLI 环境下会对输出做 HTML 转义,但仍只建议在开发环境开启。
  • PHPErrors::$errorReportLevel 是静态属性,所有实例共享。

推荐的 php.ini 配置

开发和生产环境都建议关闭 PHP 自带的错误输出,统一交给本组件处理:

display_errors = Off
display_startup_errors = Off
log_errors = On
; 备用日志位置(绝对路径,或设为 syslog),仅在未设置日志记录器时使用
error_log = /path/to/php_errors.log
error_reporting = E_ALL

php-fpm 环境下还需在 pool 配置(通常为 /path/to/fpm/pool.d/www.conf)中开启:

catch_workers_output = yes

从 php-errors/php-errors 迁移

本包改造自 php-errors/php-errors,命名空间保持不变(PHPErrors\),替换依赖即可:

composer remove php-errors/php-errors
composer require ugeek/php-errors

常规用法(enable() + PSR-3 日志记录器)无需修改代码,但相比原包有以下不兼容变化:

  • 最低 PHP 版本提升至 8.5
  • setLogger() 只接受 Psr\Log\LoggerInterface 实现
  • 方法参数和公开属性增加了类型声明,例如 enable(E_ALL, null) 会抛出 TypeError;继承并重写方法的子类需要同步签名
  • 异常日志新增异常类名前缀,Error 的调用栈改为真实出错位置
  • enable(0) 不再被视为 E_ALL

测试

composer install
composer test

License

MIT,感谢原作者 Koma 的 php-errors/php-errors。