跳转到主内容
websoft网络软件专家 - 深耕网络技术,打造实用软件!

怎样在CodeIgniter中使用Bugsnag_CodeIgniter错误报告服务【报告】

Bugsnag 无官方 CodeIgniter SDK,需手动集成:CI3 要重写 MY_Exceptions 类覆盖 show_exception() 和 show_php_error() 并提前配置;CI4 则通过中间件注入,注意禁用 Whoops、调整注册顺序,并补充请求与用户上下文。
Bugsnag
本身没有官方维护的
CodeIgniter
专用 SDK,但你可以通过 Composer 引入通用 PHP SDK,并手动集成到 CodeIgniter(尤其是 CI3)中实现错误上报。关键不是“能不能用”,而是“怎么绕过框架默认错误处理、确保异常不被吞掉”。 为什么直接 require bugsnag/bugsnag 会失效 CodeIgniter 3 的错误处理链路是:PHP 错误 →
set_error_handler()
→ CI 自己的
_error_handler()
→
show_error()
或写日志 → 静默退出 。这意味着未捕获异常根本不会走到
Bugsnag::notifyException()
这一步。 CI3 默认把所有错误转成
show_error()
页面并调用
exit()
,
Bugsnag
的自动监听器(如
register_shutdown_function
)来不及触发
Bugsnag::registerCallback()
必须在异常抛出前就注册好,而 CI 的
Exceptions
类在报错时才初始化 如果你在控制器里手动
Bugsnag::notifyException($e)
,没问题;但框架级崩溃(如路由找不到、数据库连接失败、类加载失败)你根本抓不到对象 必须重写 CI3 的 Exceptions 类 最可靠的方式是替换掉
system/core/Exceptions.php
—— 但更安全的做法是继承它,在
application/core/MY_Exceptions.php
中覆盖关键方法: 重写
show_exception()
:在调用父方法前,先执行
Bugsnag::notifyException($exception)
重写
show_php_error()
:对
E_ERROR
、
E_PARSE
等致命错误,用
Bugsnag::notifyError()
手动上报(注意:这类错误无法 throw Exception,只能传 message + code) 确保
Bugsnag::configure()
在
MY_Exceptions
构造函数或
__construct()
中完成,且 API key 来自环境变量或配置文件,不要硬编码 示例片段(
application/core/MY_Exceptions.php
):
class MY_Exceptions extends CI_Exceptions { public function __construct() { parent::__construct(); // 初始化 Bugsnag(需提前 require vendor/autoload.php) \Bugsnag\Bugsnag::configure([ 'apiKey' => getenv('BUGSNAG_API_KEY') ?: config_item('bugsnag_api_key'), ]); } public function show_exception($exception) { \Bugsnag\Bugsnag::notifyException($exception); parent::show_exception($exception); } public function show_php_error($severity, $message, $filepath, $line) { if (in_array($severity, [E_ERROR, E_PARSE, E_CORE_ERROR, E_COMPILE_ERROR])) { \Bugsnag\Bugsnag::notifyError($message, $severity, [ 'file' => $filepath, 'line' => $line ]); } parent::show_php_error($severity, $message, $filepath, $line); } }
CI4 的集成更简单但仍有陷阱 CodeIgniter 4 使用 PSR-15 中间件和现代异常处理机制,
Bugsnag
可以通过中间件注入,但要注意两点: CI4 默认启用
Whoops
错误页面(开发环境),它会拦截异常并渲染 HTML,导致
Bugsnag
收不到 —— 必须在
app/Config/Exceptions.php
中禁用:
public bool $log = true;
且
public bool $show = false;
(生产环境) 中间件注册顺序很重要:你的 Bugsnag 中间件必须放在最外层(
app/Config/Toolbar.php
或
app/Config/Filters.php
中靠前),否则被其他中间件提前
return
就失效了 CI4 的
Services::exceptions()
是单例,可直接在中间件中调用
$this->exceptions->log()
后再发给 Bugsnag,避免重复上报 别忽略 HTTP 上下文和用户标识 单纯上报异常堆栈没用,
Bugsnag
的价值在于关联请求现场。CI3 没有统一的 request 对象,你需要手动提取: 在
MY_Exceptions::show_exception()
中,用
$_SERVER['REQUEST_URI']
、
$_SERVER['REQUEST_METHOD']
、
$this->input->ip_address()
(需加载 Input 类)补全 metadata 用户信息不能依赖 session(可能已销毁),优先用
$this->session->has_userdata('user_id')
安全判断后再附加 CI4 可直接用
service('request')
和
service('session')
,但注意:异常发生在中间件链早期时,session 可能尚未启动,要加
try/catch
包裹 真正容易被忽略的是:CI 的
show_404()
不抛异常,它只是输出页面并 exit —— 这类“业务错误”不会进 Bugsnag,必须在路由或控制器里主动
Bugsnag::leaveBreadcrumb('404 on '.$uri)
或
notifyException(new RuntimeException("404: $uri"))
。

相关文章