ThinkPHP6.x行为日志:记录用户操作轨迹与系统关键事件

秋婷大大_4136

秋婷大大_4136

2026-06-13

662人浏览

原创

需结构化审计日志:一、中间件统一拦截请求记录轨迹;二、行为钩子捕获登录登出等关键事件;三、数据库监听器追踪sql变更;四、自定义审计日志驱动分离存储;五、异步队列写入防性能阻塞。

thinkphp6.x行为日志:记录用户操作轨迹与系统关键事件

如果您在ThinkPHP6.x应用中需完整还原用户操作路径并捕获系统关键事件,但当前日志仅零散存在于runtime/log/或缺失上下文字段,则说明行为审计链路尚未结构化覆盖请求生命周期与业务节点。以下是解决此问题的步骤:

一、通过中间件统一拦截HTTP请求并记录轨迹

该方法在路由调度完成、控制器执行前捕获完整请求上下文,确保所有受控接口(除明确排除项外)均被覆盖,且能安全获取认证用户ID、真实客户端IP、设备指纹、请求参数及执行耗时,形成可串联的访问链路。

1、执行命令行生成中间件:php think make:middleware OperationTraceMiddleware。

2、在OperationTraceMiddleware的handle()方法开头调用microtime(true)记录起始时间戳,并通过$request->session()->get('user_id')获取登录态ID;若session未启动,则跳过用户字段写入。

3、构造设备指纹:拼接$request->header('User-Agent').$request->ip().$request->header('Accept-Language')后取md5值,存入device_fingerprint字段。

4、使用$request->rule()->getModule()、$request->rule()->getController()和$request->action()提取模块、控制器与动作名,组合为module/controller/action格式作为action字段值。

5、调用$request->except(['token', 'password', 'sign'])过滤敏感键后,再用$request->param()获取脱敏参数数组,并对过长字段如User-Agent执行mb_strcut($ua, 0, 200)截断。

6、构造日志数据数组,包含user_id(INT或NULL)、action(VARCHAR(100))、method(CHAR(10))、ip(VARCHAR(45))、device_fingerprint(CHAR(32))、params(JSON或TEXT)、duration_ms(FLOAT)、created_at(DATETIME),并使用json_encode($logData, JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES)序列化。

7、插入数据库前检查是否匹配预设关键路由规则,例如Str::is('admin/user/*', $request->url()) || Str::is('api/v1/order/create', $request->url()),仅对匹配项写入。

二、利用行为钩子捕获登录、登出、权限变更等离散关键事件

该方法适用于由特定业务逻辑触发的非连续性事件,通过自定义钩子解耦日志代码与主流程,避免污染核心认证与权限逻辑,同时保证事件发生时机精准可控,且不依赖中间件生命周期。

1、在app/controller/Login.php登录成功分支末尾添加:Hook::listen('login_success', ['uid' => $user['id'], 'username' => $user['username'], 'ip' => request()->ip(), 'role_ids' => $user['role_ids']])。

2、在app/common/behavior/LoginLogBehavior.php中实现handle()方法,从参数中提取必要字段,构造最小审计数据,避免执行耗时操作(如查库、发HTTP请求)。

3、在登出逻辑(如app/controller/Logout.php)末尾调用Hook::listen('logout', ['uid' => session('user_id'), 'ip' => request()->ip()])。

4、在权限分配控制器(如app/controller/Admin/RoleAssign.php)中,于assign()方法成功提交后触发Hook::listen('permission_assigned', ['admin_id' => $adminId, 'target_uid' => $targetUid, 'permissions' => $perms])。

5、确保app/provider.php中已注册该行为类,例如返回数组包含'app\common\behavior\LoginLogBehavior',且类命名与路径严格符合框架约定。

三、通过数据库事件监听器追踪SQL执行细节与数据变更

该方法在模型层拦截INSERT、UPDATE、DELETE等写操作,捕获原始SQL、影响行数、关联主键及变更前后数据快照,用于回溯敏感数据修改过程,补充中间件与钩子无法覆盖的数据层行为。

1、创建监听器类app/listener/ModelChangeListener.php,监听think\model\event\AfterWrite、think\model\event\AfterDelete等事件。

2、在AfterWrite事件处理中,通过$event->model->name()获取表名,$event->model->getOriginData()获取变更前数据,$event->model->getData()获取变更后数据。

btpanel phpsite 宝塔面板PHP网站
btpanel phpsite 宝塔面板PHP网站

宝塔面板 PHP 网站管理:站点创建、删除、启停、PHP 版本切换、域名管理、SSL证书管理、伪静态管理、数据库管理

下载

3、对password、api_key等敏感字段执行显式屏蔽,仅保留字段名与变更标识(如“已更新”、“已重置”)。

4、提取主键值(如$id = $event->model->getPkValue()),并拼接为record_id字段;若为新增操作,使用$event->model->getLastInsID()获取自增ID。

5、构造变更日志条目,含table_name、operation(INSERT/UPDATE/DELETE)、record_id、before_data(JSON)、after_data(JSON)、operator_id(从Auth或Session提取)、ip(request()->ip())、created_at,写入audit_model_changes表。

6、在config/database.php中启用事件监听,确保'trigger' => true配置已开启,并在对应模型类顶部声明use think\model\Pivot;或继承基类以支持事件触发。

四、新建专用审计日志驱动,强制分离存储路径与格式

该方法规避框架默认Log::write()混存于runtime/log/导致的检索困难、无用户上下文、不可结构化查询等问题,通过自定义驱动强制将审计日志写入独立目录与结构化格式,保障日志可溯源、可筛选、可聚合。

1、新建驱动类app/log/driver/AuditFile.php,继承think\log\driver\File,并重写save()方法,强制指定日志路径为runtime/audit/。

2、在save()方法中,对传入$data参数进行预处理:提取user_id(从Auth或Session)、ip(request()->ip())、action(如"admin.user.delete")、payload(关键业务字段JSON,如{"id":123,"reason":"test"})。

3、禁止记录原始$_POST或$request->param()全量数据,仅允许显式传入经业务层裁剪后的字段集合。

4、日志文件名按日期分片,格式为audit_Y-m-d.log,每行一条JSON记录,含trace_id(UUID v4生成)、timestamp(microtime(true))、level(固定为"audit")。

5、在config/log.php中注册该驱动:'audit' => ['type' => 'AuditFile', 'path' => runtime_path() . 'audit' . DIRECTORY_SEPARATOR]。

6、在中间件或钩子中调用Log::channel('audit')->info('', $logData)写入,而非使用默认通道。

五、异步写入日志以规避高并发性能阻塞

该方法防止同步IO操作(如file_put_contents或直接数据库插入)在高并发场景下拖慢接口响应,尤其当磁盘I/O延迟或日志量激增时,确保主业务流程不受日志写入影响。

1、安装think-queue扩展:composer require topthink/think-queue,并配置Redis或Database作为队列连接。

2、定义日志任务类app/job/WriteAuditLogJob.php,实现Fireable接口,在fire()方法中接收$logData数组并执行数据库插入或文件写入。

3、在OperationTraceMiddleware的handle()末尾,将日志数据推入队列:Queue::push(WriteAuditLogJob::class, $logData)。

4、在行为钩子处理类中,同样改用Queue::push()投递,禁止在handle()中执行任何同步落库或写文件操作。

5、启动消费者进程:php think queue:listen --queue=default,确保后台持续消费日志任务。

6、对失败任务设置最大重试次数(如3次)与失败回调,失败日志单独写入runtime/queue_failed/目录,便于人工干预。

php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!

相关文章

PHP速学教程(入门到精通)
PHP速学教程(入门到精通)

PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!

下载

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
php文件怎么打开
php文件怎么打开

打开php文件步骤:1、选择文本编辑器;2、在选择的文本编辑器中,创建一个新的文件,并将其保存为.php文件;3、在创建的PHP文件中,编写PHP代码;4、要在本地计算机上运行PHP文件,需要设置一个服务器环境;5、安装服务器环境后,需要将PHP文件放入服务器目录中;6、一旦将PHP文件放入服务器目录中,就可以通过浏览器来运行它。

2023.09.01

10044

6

php怎么取出数组的前几个元素
php怎么取出数组的前几个元素

取出php数组的前几个元素的方法有使用array_slice()函数、使用array_splice()函数、使用循环遍历、使用array_slice()函数和array_values()函数等。本专题为大家提供php数组相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

5961

5

php反序列化失败怎么办
php反序列化失败怎么办

php反序列化失败的解决办法检查序列化数据。检查类定义、检查错误日志、更新PHP版本和应用安全措施等。本专题为大家提供php反序列化相关的文章、下载、课程内容,供大家免费下载体验。

2023.10.11

2075

5

php怎么连接mssql数据库
php怎么连接mssql数据库

连接方法:1、通过mssql_系列函数;2、通过sqlsrv_系列函数;3、通过odbc方式连接;4、通过PDO方式;5、通过COM方式连接。想了解php怎么连接mssql数据库的详细内容,可以访问下面的文章。

2023.10.23

3748

4

php连接mssql数据库的方法
php连接mssql数据库的方法

php连接mssql数据库的方法有使用PHP的MSSQL扩展、使用PDO等。想了解更多php连接mssql数据库相关内容,可以阅读本专题下面的文章。

2023.10.23

4434

6

html怎么上传
html怎么上传

html通过使用HTML表单、JavaScript和PHP上传。更多关于html的问题详细请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.03

3471

9

PHP出现乱码怎么解决
PHP出现乱码怎么解决

PHP出现乱码可以通过修改PHP文件头部的字符编码设置、检查PHP文件的编码格式、检查数据库连接设置和检查HTML页面的字符编码设置来解决。更多关于php乱码的问题详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.09

4957

8

php文件怎么在手机上打开
php文件怎么在手机上打开

php文件在手机上打开需要在手机上搭建一个能够运行php的服务器环境,并将php文件上传到服务器上。再在手机上的浏览器中输入服务器的IP地址或域名,加上php文件的路径,即可打开php文件并查看其内容。更多关于php相关问题,详情请看本专题下面的文章。php中文网欢迎大家前来学习。

2023.11.13

3882

8

sprintf函数用法详解
sprintf函数用法详解

sprintf函数的用法:1、格式化字符串;2、指定输出宽度和精度;3、返回值。更多关于sprintf函数用法详解的内容,大家可以阅读下面的文章。

2023.11.27

11862

4

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程