应让异常自然抛出并由全局异常处理器统一记录日志,配合中间件补全上下文、配置独立数据库日志渠道、业务异常用标准异常类抛出。

在 ThinkPHP6.0 中,控制器内**不推荐手动 try-catch 写日志**——这容易遗漏异常分支、重复记录、破坏统一审计逻辑。真正可靠的做法是:**让异常自然抛出,由全局异常处理器接管并写入日志**,同时配合中间件补全操作上下文。以下是关键路径和实操要点:
用自定义异常处理器统一捕获并落库
在 app/common/service/ExceptionHandle.php 中继承 think\exception\Handle,重写 render 方法:
- 判断异常类型(
ValidateException、HttpException、DbException等),填充结构化日志数组 - 调用模型保存到数据库,例如:
(new \app\common\model\ExceptionLog)->save($logData) - 注意:不要直接 return 响应,先记录再交由父类处理,或按需构造 JSON 返回
中间件补全请求上下文,避免日志信息缺失
单独建中间件(如 app/middleware/AdminLogMiddleware.php)拦截所有后台请求:
- 在
handle()中获取$request->controller()、$request->action()、$request->param() - 敏感操作(如 delete、status=0)可加
$request->isDelete()或$request->isPost()判断 - 原始参数建议用
$request->getRawContent()(POST/JSON)或$request->server('QUERY_STRING')(GET),避免input()过滤后失真
配置独立日志渠道,确保审计日志可查可控
在 config/log.php 中新增 admin 渠道:
- 驱动设为
database,指定表名(如log_admin),字段含user_id、ip、url、input(json_encode 后存储)、result_code - 中间件中必须显式调用
Log::channel('admin')->info(...),否则默认进single文件渠道 - 过滤敏感字段:记录
$param前,unset(password、token等键)
验证失败等业务异常,用标准类抛出而非 return
控制器里不要写 return json(['code'=>1001]) 绕过异常链:
- 参数校验失败 → 直接抛
throw new ValidateException('用户名不能为空') - 业务规则不满足 → 自定义
BusinessException类,带$code和$httpCode - 数据库操作失败 → 让
DbException自然透出,异常处理器自动捕获
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











