Using $_SESSION to Persist Form Input

May 24, 2007

In my previous projects, I’ve always used the query string for setting initial or previously submitted values to the forms. Something like:

http://some.domain.com/ourformpage.php?error=1&somefield=bob

This is fine and works well, but doesn’t work so well if you want to return long lines of text or huge data. For this, I’ve decided to use the $_SESSION variable.

When the user submits the form, the form action or handler checks the data, and in cases of errors, the form values are stored in the $_SESSION variable which are then fetched by the form after the redirection.

This works fine, as long as you keep in mind that the values you store in $_SESSION are accessible from all your active connections. Meaning if you open the same form several times and work on all of them at the same time, then you
might encounter overlapping values or previous values from one form showing up in another.

To address this issue, we create a token unique to that form instance which is included in the requests between the form and form handler. This token is then used to index an array in my $_SESSION var containing all the previous inputs for that form.

Can’t explain it too well but here’s a basic implementation. In our form page, we have:

<?php
$token = isset( $_GET['token'] ) ? $_GET['token'] : md5( time().’SOME_SECRET_KEY’ ) ;
$previous_input = isset( $_SESSION[$token] ) ? $_SESSION[$token] : array() ;
?>
<form method=”post” action=”myscript.handler.php”>
<input type=”hidden” name=”token” value=”<?php echo htmlentities( $token ); ?>” />
<input type=”text” name=”somefield” value=”<?php echo isset( $previous_input['somefield'] ) ? htmlentities( $previous_input['somefield'] ) : ” ; ?>” />
<input type=”submit” value=”Submit” />
</form>

And in our handler script myscript.handler.php, we have something like:

// get our token and input data
$token = isset( $_POST['token'] ) ? $_POST['token'] : md5( time().’SOME_SECRET_KEY’ ) ;
$somefield = isset( $_POST['somefield'] ) ? $_POST['somefield'] : ” ;

// persist data using our unique token
$arr = array();
$arr['somefield'] = $somefield;
$_SESSION[$token] = $arr;

Don’t forget to pass the token value to our form during redirection, so the form can fetch the previous values.

header( 'Location: ourformpage.php?token='.$token );

Note that the code shown is simplified for demo purposes. When doing this in your project, remember to filter all input and escape your output.

Another thing to note is in our code sample, we used time() for creating unique form tokens. This means our form values won’t overlap unless the user opens several forms within a second. Just improve on this for better resolution.