I spend allot of time creating forms. Lots and lots of forms. Most of the development time is spent to validating and cleaning the data of these forms. Normally I do light validation client side with jQuery and then strong validation on the server side with php. Only after the data passes do I actually do something with it, which usually includes cleaning or filtering first.
The Problem
If the submitted form doesn’t pass validation I want to return the data so the user doesn’t have to re-enter all the information. I don’t want to rely on javascript, although I will add it for user convenience as a final step. I also don’t want the form re-submitted if the user refreshes.
The Solution
There are quite a few ways to solve these problems. My standard approach is to post the form to a processing page and store the POST variables in a session. If the data fails the validation I redirect to the original form, pull the submitted data out of the session variables and re-populate the form with an error message.
Pretty straight forward for small contact forms. Once you get to a gigantic form that makes your eyes bleed this becomes cumbersome. On a side not I try to push my clients to the smallest possible forms they can get away with..
I use a postToSession class to make this go a little quicker.
Example Usage
I’ll use three files for my example. Comments are in the source files.
You can see a working demo of these files in action here.
Basically by using this class I can automatically serialize the form value and stuff it into a session variable. Once I unpack it, it cleans itself up.
Lets start with process.php. The form has been submitted. We instantiate the postToSession class and pass a parameter of _formValues to the constructor. This is the name of the session variable we’ll use.
$session = new postToSession( '_formValues' );
Next we’ll serialize the post values and store them in the session variable.
$session->serializePost();
Now that you’ve saved the posted values you can work validation to your hearts content and set any error messages according. If no error messages are sent the data is ready to go. In this example I simply set a status message and pass them back to the original page. If an error message is set I’ll send them back with failed in the query string.
Either way they are going back to the index page. On index.php I’ll look for the failed variable in the query string. If its set I can pull all the values back out and re-populate the form. I’ll put the values in a local array called $formValues.
$formValues = $session->unserializePost();
Now I’ll assign the form values to print out to the user. If it $_GET['failed'] isn’t set I know we either passed form validation or its a fresh start. I’ll also check to see if there is a status message set in the $_SESSION variables. If it is I’ll assign it to a local variable for display and clear it.
The End
This is just one of those little tricks I wish someone had shown me when I started. By using a separate page to process and redirecting after processing we can keep the user from submitting multiple times by pressing the refresh button. You could just as easily use the query string to repopulate the form but it looks horrible. I also use this method because many times the form is pre-populated with information like the users profile or other account information. I can use the same template for adding new records as well as editing existing records.