views:

296

answers:

4

I always use the Post/Redirect/Get method on my forms. My forms generally always submit to themselves. However, when I have an error in the form, I don't send any new headers. This is so I can easily do stuff like this

<input type="text" name="email" value="<?php echo $this->input->post('email', '') ?>" />

The PHP is just a library function that handles 2 arguments, the $_POST key and a default value if it isn't present.

This means if someone makes an error in the form, they don't have to refill out the form a second time. The disadvantage is that reloading the page gives them the POST warning in their browser.

Is there anyway to avoid this, without using something for state (i.e. cookies, session, database etc)

+1  A: 

I find the best way to do this is use the header fucntion. You can post to what ever file you need even itself do the validation then use the header redirect to go back to the form if it failed. Store the post'd values in the session or another accessible variable, therefor you can access the previously entered data.

When using header("location: myscript.php"); make sure to include an exit(); afterwards otherwise you will still get the POST warning on a refresh.

myscript.php

if($_POST['submit'])
{
    //check for errrors

    if ($error)
    {
        $_SESSION['myPostVars'] = $_POST;
        header("location: myscript.php");
        exit();
    }
}

<form>
    // your form code
</form>

Edit: I just noticed that you edited your question to aviod using sessions.

You could serliase the post vars you want to return and put them in the query string (sent via the header()

Lizard
I wouldn't suggest serializing the post variables into a query string. There's an unspecified limit as to how long the query string can be, so if you have a large set of data being posting, the browser may truncate it. IE for example will truncate anything after 1k
Chris Gow
Not to mention that (i) the urls will be logged (ii) people might tamper with the data
Salman A
You need to use sessions or cookies or some mechanism to pre-populate the data once the user is header( "location" )ed back to the page.
Salman A
A: 

You're basically doing it right. There's no particularly good way avoid the "repost" warnings.

timdev
A: 

I think you mean something like this:

function Value($array, $key, $default = false)
{
    if (is_array($array) === true)
    {
     settype($key, 'array');

     foreach ($key as $value)
     {
      if (array_key_exists($value, $array) === false)
      {
       return $default;
      }

      $array = $array[$value];
     }

     return htmlspecialchars($array);
    }

    return $default;
}

<input type="text" name="email" value="<?= Value($_POST, 'email', ''); ?>" />

You may also want to read this tutorial.

Alix Axel
The implementation I am using is the input library from Kohana (http://www.kohanaphp.com)
alex
+1  A: 

There is no way to avoid this without saving state in the session. When you encounter an error you could probably do something like the following:

  1. generate a unique id
  2. copy the $_POST variable into the session keyed by the unique id above
  3. redirect as you do now, but pass the unique id as part of the query string
  4. update your library to look for this unique id in the session (error situations) instead of accessing the $_POST variable directly, if the unique id wasn't passed on the request or the name you are looking for doesn't exist use the default value
  5. at the end of the request remove the unique id entry from the session. this saves polluting the session with too much garbage. You could also do this at the beginning of the request depending on your library
Chris Gow