Sentry适用于全链路错误监控与生产上报,PHPBrake专注轻量上报,Whoops仅限本地开发调试;三者不可混用,选错会导致功能缺失或安全风险。

直接用 composer require 装一个错误处理包(比如 sentry/sentry 或 php-brake/phpbrake),再在入口文件里初始化,就能让整个项目共享一套异常捕获逻辑——但前提是别漏掉自动加载、环境隔离和错误类型覆盖这三处关键环节。
怎么选包:Sentry、PHPBrake、Whoops 各自适用什么场景
选错包会导致功能冗余或关键链路失效:
-
whoops只适合本地开发:它把错误渲染成带堆栈的 HTML 页面,不能上报、不支持异步、生产环境启用等于暴露调试信息 -
sentry/sentry是全链路方案:支持 PHP 7.2+,能捕获Exception、Error(含TypeError、ValueError)、未捕获的致命错误(需配合register_shutdown_function),还自带采样、上下文附加、Release tracking -
php-brake/phpbrake更轻量:专注错误上报本身,不带 UI 和 SDK 管理,适合已用 Airbrake 或想最小侵入集成的项目
注意:PHP 8.5+ 的 EngineError(如 OOM)无法被 try/catch 捕获,必须靠 set_error_handler + register_shutdown_function 组合兜底,Sentry 默认已内置该逻辑,PHPBrake 需手动补。
全局初始化:别只写一次 require_once 'vendor/autoload.php'
入口文件(如 public/index.php)里初始化错误处理器是基础,但容易忽略两点:
围绕关键发现、作用机制、临床相关性及研究局限性展开讨论。适用于撰写或优化任何生物医学论文的“讨论(Discussion)”部分——包括结果解读、与既往文献关联、阐释意外发现、界定研究局限性,以及撰写结论。当用户输入以下任一指令时也会自动触发该功能: - “write my discussion” - “help me discuss my findings” - “how do I compare to prior studies” - “write the limitations par
- 必须在
require_once 'vendor/autoload.php'之后立即注册,否则类找不到; - 若项目有多个入口(CLI 命令、队列 worker、WebSocket server),每个入口都得单独初始化,不能指望“一次配置全项目生效”;
- 环境判断要硬编码,别依赖
$_ENV或getenv()——它们可能被 CLI 的-d参数或 DockerENV覆盖,建议用file_exists(__DIR__.'/../.env.production')这类物理存在判断。
示例(Sentry):
require_once __DIR__ . '/../vendor/autoload.php';
if (file_exists(__DIR__ . '/../.env.production')) {
\Sentry\init(['dsn' => 'https://xxx@o123.ingest.sentry.io/456']);
}
自动加载陷阱:autoload-dev 会污染生产环境
很多错误处理包(如 symfony/var-dumper)被列为 require-dev,但 Sentry 的 Tracing 功能依赖它。如果只跑 composer install --no-dev,就会在调用 \Sentry\configureScope() 时抛出 Class not found。
- 解决方案不是去掉
--no-dev,而是把 Sentry 相关依赖明确移到require,哪怕它带了 dev-only 的工具类; - 检查
composer.json中是否误将sentry/sentry放在require-dev下——它不是开发工具,是运行时组件; - 执行
composer dump-autoload --optimize后,用composer show -p sentry/sentry确认类路径是否已纳入主 autoload map。
错误类型覆盖:PHP 8.5+ 的 Error 子类必须显式监听
PHP 8.5 引入更严格的错误分类,ValueError、TypeError、ArgumentCountError 全部继承自 Error,而传统 catch (\Exception $e) 不会捕获它们。
- 必须补一层
catch (\Error $e),且顺序要在Exception之后(否则会被提前截获); - Sentry 默认已注册
set_exception_handler和set_error_handler,但如果你自己写了set_exception_handler,就得手动把Error实例传给 Sentry 的captureException(); - 致命错误(如
Fatal error: Allowed memory size exhausted)只能靠register_shutdown_function检查error_get_last(),这个逻辑 Sentry 内置了,但需确认enable_tracing关闭时它仍启用。
真正难搞的是跨进程场景:CLI 命令里触发的 EngineError(OOM)不会被 Web 入口的 Sentry 初始化捕获——每个进程必须独立初始化。

















