NYCPHP Meetup

NYPHP.org

[nycphp-talk] Form PRG revisited -- again

Cliff Hirsch cliff at pinestream.com
Fri Jun 15 13:36:15 EDT 2007


> The pattern I use goes something like:
> 
> load request subject
> define form (allowed values, expected types)
> if POST, get form values from POST (validating/filtering on the way)
> else get default form values from subject
> if POST and no validation errors {
>   use form values to update subject
>   redirect 303 to subject view
> }
> render form (with any errors marked)
> 
> I hope that's clear enough. It's not a bear to implement, but it helps
> to have a smart class for defining, validating, and rendering form
> values. Pear's HTML Form was the model for mine.

Interesting. This indicates that you are not doing a redirect to display
form errors, or are you? To eliminate the back/reload problem, shouldn't all
views be redirected after a post, whether a success or error?

I have a fairly smart form class, but drop out of it to cascade through
varying levels of validation beyond input checking...database queries,
password comparisons, product stock checks, DNA testing, political
affiliation, etc. It sounds like anything that can cause the form to be
redisplayed should be considered a form error and pulled into the form
validation routine -- probably best done with a callback. Right?

I still like the idea of saving a post to a session and immediately
redirecting. Its global is scope, which can be scary, and I haven't tested
it yet -- weekend project, but that's the beauty. Here's what I'm thinking
again, for those that fell asleep the first time:

// PRG FORM PATTERN AT TOP OF CONTROLLER
// ERROR CHECKNIG TO BE ADDED


if ($_SERVER['REQUEST_METHOD'] = 'post) {
    // Store post submission, then redirect
    $_SESSION['post'] = array('post' => $_POST,
                              'time' => now(),
                              'uri' => $_SERVER[' REQUEST_URI']);
   303 redirect to same URI
}

elseif ($_SESSION['post']['uri'] == $_SERVER['REQUEST_URI'] && now() <
$_SESSION['post']['time']+a few seconds) {
    // Retrieve post session using get method. Makes the assumption that
    // this get resulted from the redirect above. Why wouldn't it?
    $_POST[] = $_SESSION['post']['post'];
    unset($_SESSION['post']);
    // continue on our merry way as if this were a post submission
    // Everything should look like a post except $_SERVER['REQUEST_METHOD']
} else {
   // Flush session post variables, if necessary
   unset($_SESSION['post']);
}

Thought process:
1. A rendered form with errors will drop through with only the first
redirect -- perfect
2. A success form will drop through with only the first redirect -- perfect
3. An existing form that already has a success redirect will drop through
with one extra redirect step -- not a big deal, unless its really prevalent. 





More information about the talk mailing list