Form updates in PHP-MySQL
May 10, 2007 10:38 PM   Subscribe

Rather than updating the entire table every time a user updates a form (their profile page, for instance), I'd like the quickest way to detect ONLY the edited fields, and update those accordingly.

This will also be useful when updating the system activity log, such as "User John updated e-mail, telephone, password".

The conventional way is to embed a hidden "original" field in the form, and then compare both new and original values. I'm looking at a faster solution with less work - seeing that my project has a loooooot of forms & user activities.
posted by arrowhead to Computers & Internet (13 answers total) 1 user marked this as a favorite
 
Trigger updating audit table.
posted by orthogonality at 11:25 PM on May 10, 2007


Unless this is an academic exercise, updating all fields will likely be faster and simpler than doing an extra query to fill the "original" fields in order to create a second smaller update query. You'd be doing the comparison in the browser as well, which is not the fastest environment and also adds complexity to the solution.
posted by rhizome at 1:30 AM on May 11, 2007


Unless you keep info in a table structured like

INFO_ID | INFO_TYPE | INFO_NAME | INFO_VALUE | INFO_DATE
------------------------------------------------------------------------------
1 string email arrowhead@blah 05-11-2007

and then key INFO_IDs to USER_IDs, your current solution is the best. There's some value in keeping history and caching the most recent; in particular, things like generating system activity logs are much smoother. It all depends on what your most common requests will be, and what you need to be fast/easy and what you can live with being inefficient.
posted by devilsbrigade at 2:09 AM on May 11, 2007


The conventional way is to embed a hidden "original" field in the form, and then compare both new and original values. I'm looking at a faster solution with less work - seeing that my project has a loooooot of forms & user activities.
With client side JavaScript, on page load store the current values of each form field somewhere; on form submit, compare the current values of those fields with the original values, and disable any form elements that haven't changed. Then, on the server, only update those fields that appear in the _POST array.
posted by Aidan Kehoe at 3:40 AM on May 11, 2007


What Aidan Kehoe said.

An alternative to disabling input elements onSubmit would be to add each element id to a hidden input list onChange. When the list gets posted, you just update those fields.

My way has the disadvantage of having to add the onchange attribute to every input element, whereas with Aiden's approach you could generically handle any form. But, I dunno, something about removing expected post vars altogether seems wonky to me. I'd be afraid of somehow losing some input I actually needed if something went awry.
posted by and hosted from Uranus at 7:03 AM on May 11, 2007


Oh, and
on page load store the current values of each form field somewhere;

I wouldn't bother with this. Instead, on the server side, let php 'hardcode' the current values into a javascript array.
posted by and hosted from Uranus at 7:06 AM on May 11, 2007


Not sure if this applies to PHP, but Hibernate does something similar to this on the object level.

Essentially updates look something like this:
1. Get record you are updating from DB and fill into object.
2. Copy form field values into object
3. Persist object

When you set the field of the object, if they value is the same it won't make the change, but if they differ it will change and set a dirty flag that says 'this field has been changed.' Then when you get to the persist object step the SQL update is built dynamically to only contain changed fields.

This means that for an update you are doing another get, and this overhead is sometimes undesired, but sometimes this is very useful (concurrency/versioning of records, objects with very large numbers of fields, field-level security, etc.)
posted by cmicali at 7:21 AM on May 11, 2007


Unobtrusive HTML might work for something like this. You create a javascript include that loops through all inputs and stores them. On submit, it checks the current values for all inputs and removes them if they still match the old values (except I guess for hidden fields, which probably contain the record id).

Then you'd need to change the code on the back end so it didn't necessarily expect all fields to be returned by the form.

But I agree that changing all the fields should not be a big deal. If your tables have a ridiculously huge number of fields, then you're doing something wrong.
posted by Deathalicious at 8:55 AM on May 11, 2007


as usual, orthogonality has what looks like the 'best-practice', easiest and most elegant solution, as long as your MySQL version supports it (looks like 5.0.2 and above). See here for more details. Basically, you should be able to cause your DB to auto-update your log file with only the changed fields on every UPDATE or INSERT statement. You'd only need to build this trigger for each affected table rather than modifying each form.

i'd recommend against any system that values user-submitted data of the 'old' records over what the database says. I can't think of any scenario where this would cause security problems (unless you were doing other things totally wrong as well), but my belief is that it is good practice to trust the db over the user, as presumedly, it already contains validated data.

I'm must admit I'm a little confused by what you mean by 'Rather than updating the entire table every time a user updates a form (their profile page, for instance)' -- i suppose if your database is normalized you may get to 'skip' a few queries (you might look into using views in this instance), so I suppose I could be missing the point of your question (and thus giving bad advice). do you have an example you could share?
posted by fishfucker at 2:11 PM on May 11, 2007


er, sorry -- had a bit of a run-on sentence in my last paragraph there due to haphazard last minute editing.

my question is -- what are you trying to accomplish by only updating 'changed' fields, rather than wholesale sticking all of them in there, changed or not?
posted by fishfucker at 2:12 PM on May 11, 2007


why not hidden fields with the original value?

if foo != foo1
update
posted by Mick at 2:58 PM on May 11, 2007


Response by poster: fishfucker: my question is -- what are you trying to accomplish by only updating 'changed' fields, rather than wholesale sticking all of them in there, changed or not?

I'm developing an extranet for a company that will be used by both their staff and clients. There's a quite a few screens where the content can be updated by users, while some are limited to admins.

The project sponsor wants an "activity log" of all that's happening in the system - and that includes a record of any database insert or update activities. I'm trying to work on a method that detects only the changed fields, so that the system log will produce something specific like "User John updated e-mail, telephone, password" rather than a general "User John updated his profile".

Additionally, I am thinking that with the same method, I can update only those changed fields in the database so that it will be more efficient everytime an update SQL is run.

Many thanks in advance for all replies - I'm reading up on the "trigger" suggestion - any other ideas will be much appreciated.
posted by arrowhead at 8:18 AM on May 13, 2007


yeah, it looks like a trigger is really going to suit you well for the activity log.

as far as 'saving' work by only updating specific fields, my guess is that the calculation of finding those fields will be greater than the time it would take to just update all of them, particularly if there are few tables involved. I wouldn't worry too much about it.
posted by fishfucker at 9:03 AM on May 13, 2007


« Older my caninis erocticus has spondylosis   |   I am not my own grandpa, Experian! Newer »
This thread is closed to new comments.