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

时间:2022-06-16 05:10:41

I need to add an entry into a database everytime a field changes in a form indicating the old value and the new value.

每当字段在表单中更改时,我需要在数据库中添加一个条目,指示旧值和新值。

How would you go about this??

你会怎么做?

Would you...

  1. Add a hidden field for every field and compare it to the new value on submit then add an audit entry if neccessary??

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

  2. Do a select of the data to be inserted on post then compare each property and insert audit entry.

    选择要在帖子上插入的数据然后比较每个属性并插入审核条目。

  3. Any other ideas?

    还有其他想法吗?

Cheers.

5 个解决方案

#1


Assuming you want to keep this in the app layer I would advice to use a model layer with properties per field to do the logging. All data access then goes trough this data model, giving you a hook to add functionality.

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

An activerecord based example (VBScript):

基于活动记录的示例(VBScript):

   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

It might seem a bit bloated, but it is more flexible than a trigger based approach. For example you can easily implement range checks and such.

它可能看起来有点臃肿,但它比基于触发器的方法更灵活。例如,您可以轻松实现范围检查等。

Secondly, when you need to write multiple entity classes you can push a lot of functionality in to a delegate class and use code template to write the property getter & setters.

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

#2


You may be able to use an update trigger in your database to do the comparing and auditing. (I don't have a code sample handy - sorry).

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

#3


i think that first you can serialize the form to string , and compare with the latest string , to see if something change . if 2 string equal you have nothing to do.

我认为首先你可以将表单序列化为字符串,并与最新的字符串进行比较,看看是否有变化。如果2个字符串相等则你无关。

i supposed that all element in your form named by [] like :

我认为你的表单中的所有元素都由[]命名,如:

form_name['first_name'] .... form_name['last_name'] ....

form_name ['first_name'] .... form_name ['last_name'] ....

if you using php you can do array_diff_assoc , to see what change.

如果你使用php,你可以做array_diff_assoc,看看有什么变化。

all you need is save every time in db the latest form array , save as string by serialized .

所有你需要的是每次在db中保存最新的表单数组,通过序列化保存为字符串。

#4


You din't say what database you are using. You can try writing a procedure, which gets the current value and compare, store in database. I suggest this as I think, this is more of a comparision to be done on database side and not on front end.

你不能说你正在使用什么数据库。您可以尝试编写一个过程,该过程获取当前值并进行比较,存储在数据库中。我认为,这更像是在数据库方面而不是在前端进行的比较。

Edit: Hey, if you use Oracle it is easy to write procedures. :)

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

#5


If you're using Postgres or any other database that has functions you can easily write a function to do that for you that could be triggered whenever an UPDATE on a table is performed

如果您正在使用Postgres或任何其他具有函数的数据库,您可以轻松编写一个函数来为您执行此操作,只要执行表上的UPDATE就可以触发该函数

For point 1, It's definitely not a good idea to include 'hidden fields' in the form as someone could easily craft their own POST statement.

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

For point 2, This would work easily enough and is what I'd use if I couldn't write a function.

对于第2点,这将足够容易,如果我不能编写函数,我将使用它。

You'd wanna do something like this:

你想做这样的事情:

  1. Validate that what they are submitting is valid
  2. 验证他们提交的内容是否有效

  3. Select Information from the non-updated row
  4. 从未更新的行中选择信息

  5. Store both the form data and the db data in two arrays, for instance $db_data and $form_data
  6. 将表单数据和db数据存储在两个数组中,例如$ db_data和$ form_data

  7. Get the differences using the function array_diff_assoc

    使用函数array_diff_assoc获取差异

    $differences = array_diff_assoc($db_data,$form_data);

    $ differences = array_diff_assoc($ db_data,$ form_data);

Keeping in mind that both the form and db array need to have the same keys.

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

#1


Assuming you want to keep this in the app layer I would advice to use a model layer with properties per field to do the logging. All data access then goes trough this data model, giving you a hook to add functionality.

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

An activerecord based example (VBScript):

基于活动记录的示例(VBScript):

   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

It might seem a bit bloated, but it is more flexible than a trigger based approach. For example you can easily implement range checks and such.

它可能看起来有点臃肿,但它比基于触发器的方法更灵活。例如,您可以轻松实现范围检查等。

Secondly, when you need to write multiple entity classes you can push a lot of functionality in to a delegate class and use code template to write the property getter & setters.

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

#2


You may be able to use an update trigger in your database to do the comparing and auditing. (I don't have a code sample handy - sorry).

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

#3


i think that first you can serialize the form to string , and compare with the latest string , to see if something change . if 2 string equal you have nothing to do.

我认为首先你可以将表单序列化为字符串,并与最新的字符串进行比较,看看是否有变化。如果2个字符串相等则你无关。

i supposed that all element in your form named by [] like :

我认为你的表单中的所有元素都由[]命名,如:

form_name['first_name'] .... form_name['last_name'] ....

form_name ['first_name'] .... form_name ['last_name'] ....

if you using php you can do array_diff_assoc , to see what change.

如果你使用php,你可以做array_diff_assoc,看看有什么变化。

all you need is save every time in db the latest form array , save as string by serialized .

所有你需要的是每次在db中保存最新的表单数组,通过序列化保存为字符串。

#4


You din't say what database you are using. You can try writing a procedure, which gets the current value and compare, store in database. I suggest this as I think, this is more of a comparision to be done on database side and not on front end.

你不能说你正在使用什么数据库。您可以尝试编写一个过程,该过程获取当前值并进行比较,存储在数据库中。我认为,这更像是在数据库方面而不是在前端进行的比较。

Edit: Hey, if you use Oracle it is easy to write procedures. :)

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

#5


If you're using Postgres or any other database that has functions you can easily write a function to do that for you that could be triggered whenever an UPDATE on a table is performed

如果您正在使用Postgres或任何其他具有函数的数据库,您可以轻松编写一个函数来为您执行此操作,只要执行表上的UPDATE就可以触发该函数

For point 1, It's definitely not a good idea to include 'hidden fields' in the form as someone could easily craft their own POST statement.

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

For point 2, This would work easily enough and is what I'd use if I couldn't write a function.

对于第2点,这将足够容易,如果我不能编写函数,我将使用它。

You'd wanna do something like this:

你想做这样的事情:

  1. Validate that what they are submitting is valid
  2. 验证他们提交的内容是否有效

  3. Select Information from the non-updated row
  4. 从未更新的行中选择信息

  5. Store both the form data and the db data in two arrays, for instance $db_data and $form_data
  6. 将表单数据和db数据存储在两个数组中,例如$ db_data和$ form_data

  7. Get the differences using the function array_diff_assoc

    使用函数array_diff_assoc获取差异

    $differences = array_diff_assoc($db_data,$form_data);

    $ differences = array_diff_assoc($ db_data,$ form_data);

Keeping in mind that both the form and db array need to have the same keys.

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