Php 审核特定表单字段更改的最佳方法是什么?

Php 审核特定表单字段更改的最佳方法是什么?,php,asp.net,javascript,database,asp-classic,Php,Asp.net,Javascript,Database,Asp Classic,每当一个字段以指示旧值和新值的形式更改时,我需要向数据库中添加一个条目 你会怎么做 你会 为每个字段添加一个隐藏字段,并将其与提交时的新值进行比较,然后在必要时添加审核条目 选择要在post上插入的数据,然后比较每个属性并插入审核条目 还有其他想法吗 干杯。我认为首先可以将表单序列化为字符串, 并与最新的字符串进行比较, 看看有什么变化。 如果两个字符串相等,则无需执行任何操作 我假设表单中所有名为[]的元素如下: 表格名称[“名字”]。。。。 表格名称[姓氏] 如果您使用php,您可以执行ar

每当一个字段以指示旧值和新值的形式更改时,我需要向数据库中添加一个条目

你会怎么做

你会

  • 为每个字段添加一个隐藏字段,并将其与提交时的新值进行比较,然后在必要时添加审核条目

  • 选择要在post上插入的数据,然后比较每个属性并插入审核条目

  • 还有其他想法吗


  • 干杯。

    我认为首先可以将表单序列化为字符串, 并与最新的字符串进行比较, 看看有什么变化。 如果两个字符串相等,则无需执行任何操作

    我假设表单中所有名为[]的元素如下:

    表格名称[“名字”]。。。。 表格名称[姓氏]

    如果您使用php,您可以执行array_diff_assoc,以查看有什么变化


    您只需每次在db中保存最新的表单数组,通过序列化另存为字符串。

    您可以使用数据库中的更新触发器进行比较和审核。(我手边没有代码示例-抱歉)。

    您没有说明正在使用的数据库。您可以尝试编写一个过程,获取当前值并进行比较,然后将其存储在数据库中。我建议这样做,因为我认为,这更多的是在数据库端进行比较,而不是在前端


    编辑:嘿,如果您使用Oracle,编写过程很容易。:)

    如果您使用的是Postgres或任何其他具有函数的数据库,您可以轻松地编写一个函数来为您执行此操作,该函数可以在对表执行
    更新时触发

    对于第1点,在表单中包含
    隐藏字段
    绝对不是一个好主意,因为有些人可以轻松地编写自己的
    POST
    语句

    对于第2点,这将很容易工作,如果我不能编写函数,我会使用它

    你会想做这样的事情:

  • 验证他们提交的内容是否有效

  • 从未更新的行中选择信息

  • 将表单数据和DB数据存储在两个数组中,例如
    $DB\u data
    $form\u data

  • 使用函数获取差异


  • 请记住,表单和DB数组都需要具有相同的键。

    如果您希望将其保留在应用层中,我建议使用每个字段都具有属性的模型层来进行日志记录。然后,所有的数据访问都通过这个数据模型,为您添加功能提供了一个钩子

    基于脚本的示例(VBScript):

    类cSomeEntity
    “公共数据库”链接到数据库包装器
    私有id,脏,加载的“可变标志”
    私有子类_初始化
    脏=假
    已加载=错误
    端接头
    私有子类
    如果脏的话
    execute(“updatesome_table set some_field=?where id=?”,数组(p_some_field,id))
    如果结束
    端接头
    公共子负载按id(值)
    暗淡的
    设置rs=db.fetch_-rs(“选择id,从id=?”的某个_表中选择某个_字段,数组(id))
    id=rs(“id”)
    p_some_field=rs(“some_field”)
    已加载=真
    端接头
    私人p_某些_字段
    公共属性获取一些字段
    some_字段=p_some_字段
    端属性
    公共财产出租部分_字段(值)
    如果未加载,则err.raise 1,“实体尚未初始化,请先调用.load\u by_id()!”
    如果p_值是某个字段,则
    脏=真
    创建日志条目(“一些值”,p\u一些字段,值)
    p_某些_字段=值
    如果结束
    端属性
    专用子生成日志条目(字段、旧值、新值)
    db.execute(“插入审计日志(表、字段、旧值、新值)值(?,,?)”_
    数组(“某些_表”、字段、旧_值、新_值))
    端接头
    末级
    
    它可能看起来有点臃肿,但它比基于触发器的方法更灵活。例如,您可以轻松地执行范围检查等


    其次,当您需要编写多个实体类时,您可以将大量功能推送到委托类中,并使用代码模板编写属性getter和setters。

    还有其他限制吗?您可以使用存储过程吗?如果可以,我将使用选项2,在一个存储过程中(这将使您的应用程序保持简单),您可以使用sp,但需要知道更改值的用户。您可以将用户id作为变量之一传递给sp?您已将其标记为ASP Classic、PHP和ASP.NET。它是哪一个?它还标记了Javascript,这是一个非常糟糕的主意。不要使用客户端进行类似的操作。经典asp上的服务器端javascript。
    $differences = array_diff_assoc($db_data,$form_data);
    
       class cSomeEntity
           public db ' link to a db wrapper
           private id, dirty, loaded ' varous flags 
    
           private sub class_initialize
             dirty = false
             loaded = false
           end sub
    
           private sub class_terminate
            if dirty then
                db.execute("update some_table set some_field=? where id=?", array(p_some_field, id))
            end if
           end sub
    
           public sub load_by_id(value)
             dim rs
             set rs = db.fetch_rs("select id, some_field from some_table where id=?", array(id))
             id = rs("id")
             p_some_field = rs("some_field")        
             loaded = true
           end sub
    
           private p_some_field
           public property get some_field
             some_field = p_some_field
           end property
    
           public property let some_field(value)
             if not loaded then err.raise 1, , "Entity not yet initialized, call .load_by_id() first!"
             if value <> p_some_field then
               dirty = true
               make_log_entry("some_value", p_some_field, value)           
               p_some_field = value      
             end if
           end property
    
           private sub make_log_entry(field, old_value, new_value)
             db.execute("insert into audit_log (table, field, old_value, new_value) values (?, ?, ?, ?)", _
               array("some_table", field, old_value, new_value))     
           end sub 
        end class