应跳过已废弃的bugsnag_codeigniter包,改用官方bugsnag/bugsnag sdk手动集成;因其硬编码ci2/3机制,与ci4服务容器、psr-4加载及异常体系完全不兼容,强行安装会导致class not found等致命错误。

CodeIgniter 本身不内置 Bugsnag 集成,Bugsnag_CodeIgniter 这个包早已停止维护(最后更新在 2016 年),直接安装会因 PHP 版本、Composer 依赖或命名空间冲突导致报错,比如 Class 'Bugsnag_CodeIgniter\Bugsnag' not found 或 Cannot use Bugsnag\Bugsnag as Bugsnag because the name is already in use。你应该跳过这个废弃包,改用官方 bugsnag/bugsnag SDK + 手动适配。
为什么不能直接 require "Bugsnag_CodeIgniter"
该扩展是为 CI2/CI3 早期版本写的,硬编码了 CI_Controller 继承链、get_instance() 调用和 config/autoload.php 注册方式,与 CI4 的服务容器、PSR-4 自动加载机制完全不兼容;即使强行装上,也会在启动阶段就抛出 Fatal error: Uncaught Error: Class 'Bugsnag_CodeIgniter\Bugsnag' not found。它也不支持现代 PHP 的严格类型、返回类型声明,且无法处理 CI4 的 HTTP\Exceptions 分层异常体系。
CI4 中正确接入 Bugsnag 的三步实操
核心思路:绕过所有第三方封装,用原生 bugsnag/bugsnag SDK,在 CI4 生命周期关键节点手动注册错误处理器。
- 运行
composer require bugsnag/bugsnag(推荐 v4.x,兼容 PHP 8.1+) - 在
app/Config/Boot/production.php(或全局app/Config/Boot/common.php)末尾添加初始化代码:
use Bugsnag\Bugsnag;
use CodeIgniter\Events\Events;
// 仅在 production 环境启用
if (ENVIRONMENT === 'production') {
$bugsnag = Bugsnag::make([
'apiKey' => 'your-api-key-here',
'releaseStage' => ENVIRONMENT,
'notifyReleaseStages' => ['production'],
]);
// 捕获未捕获异常(包括控制器、中间件、命令行脚本)
set_exception_handler([$bugsnag, 'handleException']);
// 捕获 PHP 错误(E_ERROR、E_WARNING 等)
set_error_handler([$bugsnag, 'handleError'], E_ALL);
// 捕获致命错误(如 parse error、fatal error)
register_shutdown_function(function () use ($bugsnag) {
$error = error_get_last();
if ($error && in_array($error['type'], [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR, E_USER_ERROR])) {
$bugsnag->notifyError($error['type'], $error['message'], $error['file'], $error['line']);
}
});
// 可选:在 CI4 事件中注入请求上下文
Events::on('pre_system', function () use ($bugsnag) {
$request = \Config\Services::request();
$bugsnag->setMetaData([
'request' => [
'uri' => (string) $request->getUri(),
'method' => $request->getMethod(),
'ip' => $request->getIPAddress(),
],
]);
});
}
- 确保
app/Config/Constants.php中ERROR_REPORTING不被设为0,否则 PHP 错误会被静默吞掉,Bugsnag 也收不到
如何在控制器里主动上报已捕获异常
不要用 $this->bugsnag->notifyException()(没这个对象);直接调用全局实例或重新获取 SDK 实例。
- 最稳妥方式:在控制器方法中使用
service('bugsnag')—— 但需先注册一个自定义服务(见下条) - 快速方式:在 try/catch 块中直接调用
bugsnag()->notifyException($e),前提是已在 Boot 文件中把$bugsnag实例存入 CI4 的 Services 容器:
// 在 Boot 文件中初始化后追加:
\CodeIgniter\Config\Services::add('bugsnag', function () use ($bugsnag) {
return $bugsnag;
});
- 然后在控制器中:
try {
// 可能失败的逻辑
} catch (\Exception $e) {
bugsnag()->notifyException($e, [
'custom' => ['user_id' => user_id(), 'action' => 'payment_submit']
]);
throw $e; // 或返回友好提示
}
容易被忽略的两个硬性条件
CI4 + Bugsnag 能否真正生效,取决于这两个常被跳过的检查点:
-
php.ini中必须开启log_errors = On且error_log指向可写路径——Bugsnag 的 shutdown handler 依赖error_get_last(),而该函数只对未被@抑制、且未被其他 handler 拦截的致命错误有效 - CI4 的
app/Config/Exceptions.php中,$cacheReport必须为false,否则某些异常(如路由未匹配)会在到达 Bugsnag 前就被框架缓存并静默丢弃
一旦漏掉其中任一条件,你看到的现象就是:本地开发一切正常,上线后 500 错误完全不上报,连 error_log 都空空如也。











