V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
frozenway
V2EX  ›  PHP

PHP 如何记录网站后台数据的修改记录?比如谁登录了修改了某模块的其中几个字段数据

  •  
  •   frozenway · 2019-08-09 15:09:07 +08:00 · 6153 次点击
    这是一个创建于 1964 天前的主题,其中的信息可能已经有所发展或是发生改变。

    现在是用最原始的办法,每更新一个数据表前,都把表单提交过来的数据保存到一个日志表。但是这样做的话,每次表单提交过来十几个字段。每次查日志分析用户改了那些数据时,都要肉眼一个个字段去对比,好辛苦。直接两个字段用程序“==”对比,字段值太长,怕程序崩溃,想问一下,这应该怎么办?

    第 1 条附言  ·  2019-08-09 15:40:56 +08:00
    比如说我有一个用户表 user,表字段是 u_id,u_username,u_pwd,u_sex,u_phone,其中有一行数据的值是 1,zhangsan,32 位字符,男,136xxxxxxxx

    现在我要更新这行数据,值改变成 1,lisi,32 位字符,男,135xxxxxxxx

    那么更新之后我可以用什么好方法获取改变了的字段,然后保存到日志文件?比如说是 xxx 用户,把 u_username 字段值从 zhangsan 改成了 lisi,把 u_phone 字段值从 136xxxxxxxx 改成了 135xxxxxxxx。

    大概是这个意思
    22 条回复    2019-08-15 11:03:07 +08:00
    catcalse
        1
    catcalse  
       2019-08-09 15:21:48 +08:00
    去看看 版本控制器实现方法
    lihongjie0209
        2
    lihongjie0209  
       2019-08-09 15:24:31 +08:00
    service 层记录业务操作

    dao 层记录数据库变动

    二者通过一个事务 ID 关联

    主要实现方式无非是 aop
    jksusu
        3
    jksusu  
       2019-08-09 15:26:02 +08:00
    可以试试 sql 日志。对每一种数据库操作分类可视化
    laojiaqing
        4
    laojiaqing  
       2019-08-09 15:26:06 +08:00
    我是过来学习的
    rubycedar
        5
    rubycedar  
       2019-08-09 15:43:56 +08:00
    存储过程?
    opengps
        6
    opengps  
       2019-08-09 15:44:02 +08:00
    真的关键数据,那么所有增删改(除了查)都得记录到独立的操作变更表里。
    可以考虑存着新旧值; 也可以考虑只存新值,关联上一个操作查旧值
    vtwoextb
        7
    vtwoextb  
       2019-08-09 15:45:20 +08:00
    涉及到 修改数据的业务层 直接添加日志就行了
    manhere
        8
    manhere  
       2019-08-09 18:29:00 +08:00 via Android
    zjsxwc
        9
    zjsxwc  
       2019-08-09 19:11:16 +08:00 via Android
    如果用 orm 那么在每次 更新实体类对象到数据库中,
    都会提供事件,
    你只需要写一个事件订阅者,
    记录是哪个用户把这个实体类哪个字段从什么值更新为什么值就行了。


    如果你是基于纯 sql 操作数据库的,我建议写个代码生成器,把要拦截的方法都重新 proxy 一下,代替原方法,实现一个简单的 aop
    Varobjs
        10
    Varobjs  
       2019-08-09 19:16:19 +08:00 via Android
    有框架吗,框架提供 SQL 日志吗,可以再处理下,更新相关的 SQL 日志➕当前登录用户存起来
    Erroad
        11
    Erroad  
       2019-08-09 19:19:21 +08:00 via Android
    orm 对象记录 dirty field,更新和插入之后加入 hook 回写日志表
    MaxTan
        12
    MaxTan  
       2019-08-09 20:44:13 +08:00
    之前有做过类似的,
    用 aop 切面,所有的 update 操作都经过切面,对比两个 object 的差异,然后把有改动 object 的表名,列名和修改内容写到日志表
    对比差异当时是直接用反射取类成员值,就不用一个个"=="去判断了
    xiangyuecn
        13
    xiangyuecn  
       2019-08-09 21:03:17 +08:00
    很多年前我是这样做的:只在敏感操作的地方把变更数据库的语句细分出来统统记录下来,类似结构

    细分敏感操作的名称 | 谁操作的 | 操作的对象标识 | 变更 SQL 语句 | 变更时间

    好像跟你现在用的蛮像,但你的几十个数据堆一起,不难用才怪,细分一下会好很多。我的虽然简陋,但非常好用。记忆中多次帮业务人员还原误操作变更的数据。无数次客户扯皮,拉出他自己操作的变更记录马上就无话可说😁

    在没有记录变更前的数据的情况下如何还原数据?你猜😐
    starsriver
        14
    starsriver  
       2019-08-09 23:24:38 +08:00 via Android
    php 最方便的就是 db 用钩子
    starsriver
        15
    starsriver  
       2019-08-09 23:28:46 +08:00 via Android
    wc 怎么半句话就发出去了。。php 最方便的就是 db 用钩子,改一下 db 函数库里面的 update,增加一个触发器。

    或者在有数据库操作的地方做触发器,写纪录文件。

    单纯的数据库 log 开销是有点大,而且 log 更多是拿来做恢复用的,对比也很烦。
    dodosss
        16
    dodosss  
       2019-08-10 09:06:40 +08:00
    都是大神,我来说一下使用过的笨方法:
    dodosss
        17
    dodosss  
       2019-08-10 09:11:25 +08:00
    修改提交表单把修改前的内容也提交过来,然后对比不相同就记录,如接收提交的逻辑处理为:$_POST['u_phone']="138**修改后的值"; $_POST['u_phone_src']="137**修改前的值"; if($_POST['u_phone']!=$_POST['u_phone_src']){ doYourLog(); }
    wenzichel
        18
    wenzichel  
       2019-08-10 09:29:55 +08:00
    我们给产品自己使用的内部平台,操作日志很简单,就是把执行的 sql 语句放上去,因为操作日志一般是不会看,除非是出问题了要回溯的时候。真等到要查看日志的时候,这样也能看到某个人在某个时间点进行了什么操作。
    zhuzhibin
        19
    zhuzhibin  
       2019-08-10 09:41:11 +08:00 via iPhone
    如果纯粹记 log 前后端分离的话 能否统一在 rpc 那一层记 log 然后关注 payload 请求了那个接口 携带什么参数
    ben1024
        20
    ben1024  
       2019-08-10 11:19:24 +08:00
    1.binlog 监听
    .canal
    .maxwell

    2.ORM 模型触发器

    3.主动模型比对
    neetrorschach
        21
    neetrorschach  
       2019-08-15 05:23:27 +08:00
    正在做类似的功能,用的 java。
    想要达到的效果是记录每次保存操作修改了哪些字段,修改前的值和修改后的值,并区分出操作类型是增加、删除或修改。同时增加一个对比按钮,点击后在页面高亮显示最后一次被修改的字段,鼠标悬浮显示历史值。
    我的实现方法是保存时先根据 id 取出数据库内已有的记录,然后比对,最后将比对结果写入日志表。
    开发过程中被一个问题卡了很久。是关于日志 id 怎么生成的逻辑。由于页面表单数据其实是分 3 部分内容,所以是触发了 3 个请求到后端。如果第 1 部分数据有修改,那么应当生成一个新的日志 id。第 2 个请求触发时如果也查出有修改,那么记录日志时应当沿用第一个请求的日志 id。第 3 个请求也是一样。这个 id 的传递方法卡了好几天。最后是把它存到了 session 里,第 2、3 请求触发时先获取 session 内的 id,如果获取不到就新建一个。
    现在又被另一个问题卡住了。由于第 3 部分数据是一个 list,里面是 1 个或多个 model 实体对象。在比对差异的时候感觉很复杂。假设页面新增了一组数据,也就是 list 里多了一个对象。那么比对时的循环应该是用新的 list 做外循环,里面嵌套数据库内的实体 list 做比对。如果是删除操作,那么就要反过来。目前只做了第一种情况已经写了 200 行了,感觉再要写一遍 200 行,但其实逻辑基本一样,只是哪个 list 作为外循环的差异。
    非常讨厌写这种臃肿的代码。
    2kCS5c0b0ITXE5k2
        22
    2kCS5c0b0ITXE5k2  
       2019-08-15 11:03:07 +08:00 via iPhone
    写日志 每天跑个 Python 脚本去持久化到数据库
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   1004 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 26ms · UTC 20:25 · PVG 04:25 · LAX 12:25 · JFK 15:25
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.