Page 1 of 1

Form Handling Design

Posted: Sun Jun 15, 2003 10:14 am
by nielsene
I suspect that the answers here will be primarily based on personal preference, but how do you deal with form handling? I'm listing the approaches I've seen or used, if you have other patterns, please share them. I'm trying hard not to add my personal thoughts on these patterns in my opening post, but will add them later as a reply.

Single, Self-Submitting Page
I see this design fairly commonly in people's designs in the regular PHP forum section. You have a single page that handles the submission of lots of different forms and redisplays the appropriate page on success/failure.
The code tends to use either cascaded if's or a pair of switches:

Code: Select all

if ("submit"==$_POST["submit"])
{
  switch($_POST["stage"])
  {
      case "Step1" : // validate Step1's inputs + break
      case "Step2" : // validate Step2's inputs + break
       // ....
      default : // handle an unknown stage -- hack attack
  }
}
// the above section would set both a $curStage variable and any error/preload variables
switch($curStage)
{
  case "Step1" : // display the first page of the site + break
  case "Step2" : // display the second ...
   // ...
   default: // hanles an unknown stage
}
Self-submitting webpages
A series of pages, each one self-submits, but on success redirects to the next page. Model code:

Code: Select all

if ("submit"==$_POST["submit"])
{
  // validate inputs
  if ($validated)
  {
      // update db, session, etc
      header("Location: nextpage.php");
      exit;
   }
    // error strings were set during the validate input phase is needed
}
// display the page, including error strings if present
Forward Submitting Webpages
Like the above, but submit and validated on the next page, redirect back to previous page on failire.

Code: Select all

if ("submit"==$_POST["submit"])
{
  // validate inputs
  if ($validated)
  {
      // update db, session, etc
       $_SESSION["formVars"]=array();
       $_SESSION["errors"]=array();
   }
   else
   {
        $_SESSION["formVars"]=$formVars;
        $_SESSION["errors"]=$errors;
        header("Location: prevPage.php");
        exit;
   }
}
// display page using $_SESSION["formVars"/"errors"] for preloads or messages
"Interstitual" Pages
Seperate view pages from processing pages. A given viewed webpage submits to one or more processing pages. The processing page does all the validation and redirects to either successive or previous pages as needed.
Sample View Page:

Code: Select all

// display page using values in $_SESSION["formVars"/"errors"] as show above, for error handling or previously filled in values.
Sample Processing Page:

Code: Select all

if ("submit"==$_POST["submit"])
{  
   // validate, save current values form values, set error messages if
   // needed
 }
else
{
   $validated=FALSE;
}
if ($validated)
{
  // handle DB updates, setup new session variables
  header("Location: nextPage.php");
  exit;
}
else
{
   $_SESSION["formVars"]=$formVars;
   $_SESSION["errors"]=$errors;
   header("Location: prevPage.php");
   exit;
}

Now obviously, I've left out a lot of details about how each method works, but I think you can see the outline and the steps involved in each. Do you have an obvious favorite, that you use every time? All of the methods can of course use functions to pull lots of the fluff out to a seperate file, for instance all the validation or the individual page displays, etc. All the methods could be OOP or not, so that's not an issue here. Are there other paradigms to be aware of?

Posted: Mon Jun 16, 2003 3:18 am
by MrNonchalant
Generally I prefer the Single, Self-Submitting Page. It's so gratifying to have a largish application in one file.

Posted: Mon Jun 16, 2003 1:07 pm
by McGruff
Interstitial. I like to try to make code "modular" - ie different tasks clearly separated - so separate form processors work for me.

Posted: Thu Jun 19, 2003 6:26 pm
by nielsene
Yeah, I've also been using the "Interstitual" design pattern most of the time. Recently I've been working on a very data-entry intensive form, with very little processing and simple validation -- sounded to me like the right setup for the self-submitting pages. It worked beautifully for the first 6 pages or so of a 12 page process. The later pages form elements and validation requirements are heavily based on the answers to the first pages. As a result its getting more complex with more data paths and I'm realizing I should have stuck with the "Interstitual" design throughout.

However, almost all PHP books/websites promote the self-submitting version. Do you think this is because it "simpler" in terms of publishing examples to only have to deal with a single page? Or because it doesn't require as much argument passing and thus is a simpler design, even if brittle and non-scaleable?

Posted: Fri Jun 20, 2003 2:56 am
by twigletmac
It's simpler to write up examples that only use one page (less room for your readers to get confused) so I think that's why most tutorials do it this way. Same reason why many rely heavily on register_globals on and low error reporting settings.

Mac

Posted: Fri Jun 20, 2003 9:09 am
by nielsene
twigletmac wrote:It's simpler to write up examples that only use one page (less room for your readers to get confused) so I think that's why most tutorials do it this way. Same reason why many rely heavily on register_globals on and low error reporting settings.

Mac
Hmm, and then we get stuck with people who need basic training in debugging posting 200 line spaghetti code scripts asking us what's wrong... and we wonder where they learned to code like that.... Shame on us.

Posted: Fri Jun 20, 2003 10:30 am
by Gleeb
McGruff wrote:Interstitial. I like to try to make code "modular" - ie different tasks clearly separated
ME too, but what I tend to do is have them all point at one file (admin.php, say) and use include() to include the different 'steps'.

Makes for some good loooking urls when you exploit a few apache features and $_SERVER['PHP_SELF'] :) ('http://testserver/admin/postnews/' Vs. 'http://testserver/admin.php?action=postnews'... I definatly prefer the shorter one :))

Posted: Fri Jun 20, 2003 11:07 am
by patrikG
I use the "interstitual" form-handling as well - I have one base class for form-handling which, if necessary, I adapt for each application.

At the very beginning, I followed the advice in that PHP-book I had (don't remember the title, but it was appaling) and made every page handle the input itself (the "self-submitting" way). After some time I couldn't keep track of all everything that was going on - same problem you encountered, nielsene.

Personally, I find forms (read user-input) the most labour-intensive part of any application as you really have to make sure it's totally foolproof.

To me OO-"Interstitual" form-handling is a bit like the Lord of the Rings...

"One Class to rule them all,
One Class to find them,
One Class to bring them all,
and on the server bind them."

P.S.: That doesn't make me Sauron, however...:P

Posted: Fri Jun 20, 2003 11:12 am
by nielsene
In the land of Linux
where PHP thrives

Posted: Fri Jun 20, 2003 5:25 pm
by cactus
I find it's "Horses for courses", you can always guarantee that there will be a simple page that just needs to be submitted to its self to perform a desired action.

I do agree that you need to build a generic enough system to handle many kinds of form submission but you will always end up creating something that handles a specific task, forms are used and abused in so many ways its hard to be generic.

Development of an interstitial approach (IMO) is based on the type of processing involved in that interstitial page, too much processing and you could leave your user staring into space (server performance etc allowing) or even adverts ;) It's also about what the result of the form submission should be; the resultant page may be vastly different than that of the submission page hence an interstitial seems appropriate (to reduce the amount of code in the file for multi-pages disguised as single page).

My 2p :)

Regards,

Anything wrong with using both styles?

Posted: Sat Jun 21, 2003 9:07 am
by Bill H
For me the issue is readability.

For simple forms and handlers I use one file for both purposes. Easier for coding -- everything is all in one place.

At some point the "one place" becomes big enough that it is too unwieldy from a navigation standpoint when reviewing and/or editing the code.

Posted: Mon Jun 23, 2003 9:33 am
by BDKR
I prefer to use the single page approach with 'one' switch. However, I feel that it's best not to actually write out the logic in the script. Abstract it with a function or method call. In the example below, instead of all the logic fields checking, processing forms, and so on being placed withing any of the appropriate cases, they're all abstracted away.

Code: Select all

if(isset($_POST['submit']) 
  { 
    switch($_POST["submit"]) 
      { 

      case 'value1' : 
        {
        if(check_fields()==true) 
          { 
          if(process_form()==false)
            { /* do error stuff */ }
          } 
         else
           { show_form(); }
        break;
        }

      case 'value2' : 
        { 
        if(is_logged_in()==true) 
          { show_user_data(); } 
        else
          { show_form(); }
        break;
        }

      default : { show_form(); }
      } 
  }
else
  { show_form(); }
As for those that are having probs maintaining code, what editors are you using? Are you seperating specific tasks into functions or classes? If you identify areas of responsibility up front then create functions or classes as such, then coupled with a good editor, large scripts should still be easy to maintain.

Just my opinion... :?
?>