在thinkphp 6.0中通过模型静态事件(before_write、after_write、before_delete)自动记录增删改查审计日志,包含操作人、时间、ip、影响行数及变更详情,无需手动写日志逻辑。

在ThinkPHP 6.0项目中实现数据库操作审计日志,需让每次增删改查自动记录操作人、时间、影响行数及原始SQL,避免手动在每个控制器里重复写日志逻辑。
注册模型事件监听器
打开你要审计的模型文件(如app/model/User.php),在类定义内部添加静态事件方法声明。
在类开头附近添加:【protected static $event = ['before_write', 'after_write', 'before_delete'];】
这三类事件覆盖写入前、写入后、删除前三个关键节点,比只监听after_update更全面——漏掉before_delete会导致软删除或硬删除操作无法被捕获。
编写审计日志逻辑
在同一个模型文件中,依次定义以下三个静态方法:
方法一:记录写入前快照
protected static function onBeforeWrite($model) {<br> $data = $model->getData();<br> if (isset($data['id'])) {<br> // 修改操作,记录原数据<br> $original = self::find($data['id']);<br> if ($original) {<br> session('audit_snapshot', $original->toArray());<br> }<br> }<br>}
方法二:记录写入后结果
protected static function onAfterWrite($model) {<br> $action = $model->isUpdate() ? 'update' : 'insert';<br> $userId = session('user_id') ?: 0;<br> $ip = request()->ip();<br> $logData = [<br> 'user_id' => $userId,<br> 'action' => $action,<br> 'table' => $model->getTable(),<br> 'record_id' => $model->id,<br> 'ip' => $ip,<br> 'created_at' => time(),<br> ];<br> // 补充变更字段详情<br> if ($action === 'update' && $snapshot = session('audit_snapshot')) {<br> $diff = array_diff_assoc($model->getData(), $snapshot);<br> $logData['changes'] = json_encode($diff, JSON_UNESCAPED_UNICODE);<br> }<br> Db::name('audit_log')->insert($logData);<br> session('audit_snapshot', null);<br>}
方法三:拦截并记录删除行为
protected static function onBeforeDelete($model) {<br> $logData = [<br> 'user_id' => session('user_id') ?: 0,<br> 'action' => 'delete',<br> 'table' => $model->getTable(),<br> 'record_id' => $model->id,<br> 'ip' => request()->ip(),<br> 'created_at' => time(),<br> ];<br> Db::name('audit_log')->insert($logData);<br>}
注意:模型必须继承think\Model,且audit_log数据表需提前创建,包含id、user_id、action、table、record_id、ip、changes(TEXT)、created_at字段。
统一启用审计功能
第一步:在app/common.php中添加全局模型事件绑定代码
第二步:遍历所有启用审计的模型,执行Model::observe(YourAuditObserver::class) → 但TP6.0不支持observe机制
第三步:改用静态事件注册方式,在app/provider.php的register()方法末尾插入:
use think\facade\Db;<br>Db::event('after_insert', function ($query) {<br> if (method_exists($query->getModel(), 'onAfterWrite')) {<br> $query->getModel()::onAfterWrite($query->getModel());<br> }<br>});
第四步:为after_update和after_delete事件补充相同逻辑,确保三类操作全部触发。
第五步:确认app/model下所有需审计的模型均已声明$event数组并实现对应静态方法。











