PHP
  Home arrow PHP arrow Page 4 - Making PHP Forms Object-Oriented
Dev Articles Forums 
ADO.NET  
Apache  
ASP  
ASP.NET  
C#  
C++  
ColdFusion  
COM/COM+  
Delphi-Kylix  
Design Usability  
Development Cycles  
DHTML  
Embedded Tools  
Flash  
Graphic Design  
HTML  
IIS  
Interviews  
Java  
JavaScript  
MySQL  
Oracle  
Photoshop  
PHP  
Reviews  
Ruby-on-Rails  
SQL  
SQL Server  
Style Sheets  
VB.Net  
Visual Basic  
Web Authoring  
Web Services  
Web Standards  
XML  
Mobile Linux 
App Generation ROI 
IBM® developerWorks 
Sun Developer Network 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us Get Paid 
Request Media Kit
Contact Us 
Site Map 
Privacy Policy 
Support 
 USERNAME
 
 PASSWORD
 
 
  >>> SIGN UP!  
  Lost Password? 
PHP

Making PHP Forms Object-Oriented
By: Yuri Makassiouk
  • Search For More Articles!
  • Disclaimer
  • Author Terms
  • Rating: 4 stars4 stars4 stars4 stars4 stars / 29
    2003-01-23

    Table of Contents:
  • Making PHP Forms Object-Oriented
  • Analysis
  • Executing Environment
  • Implementing the FormProcessor Class
  • Inputs - Brief Introduction
  • Example of a Form
  • Conclusion

  • Rate this Article: Poor Best 
      ADD THIS ARTICLE TO:
      Del.ici.ous Digg
      Blink Simpy
      Google Spurl
      Y! MyWeb Furl
    Email Me Similar Content When Posted
    Add Developer Shed Article Feed To Your Site
    Email Article To Friend
    Print Version Of Article
    PDF Version Of Article
     
     
    ADVERTISEMENT


    Making PHP Forms Object-Oriented - Implementing the FormProcessor Class


    (Page 4 of 7 )

    But this was still quite far from our original subject, we were talking about object-oriented forms here, remember? Let's have a look at FormProcessor and see what's under its hood.

    I had to strip the code of PHPDoc-style comments, because I think it requires step-by-step explanations, while reading through the comments in arbitrary order might confuse. A version of this source with PHPDoc comments is available for download at the end of this article.

    <?php

      /**
      * An abstract class implementing generic functionality for processing user's input
      *
      * This class encapsulates generic functions for working
      * with data coming from user forms. Descendants must only override certain
      * functions that perform context-specific tasks, like custom checking of
      * data, storing correct data, etc.
      *
      * @author Yuri Makassiouk <racer@bfpg.ru>,
      *  Mission & Media <firma@missionandmedia.com>
      */
      class FormProcessor {
        var $Name;
        var $FirstTime;
        var $Values;
        var $Errors = array();
        var $ErrorMessageFormat = '<br>%s';
        var $wizardPage;
        var $fieldPrefix = 'mm_form_data_';

        function FormProcessor($Name, $wPage='') {
          $this->Name = $Name;
          $this->wizardPage = $wPage;
          
          $this->Values = $GLOBALS[$this->fieldPrefix.$this->Name];
          $this->FirstTime = (count($this->Values) == 0);

          if (!$this->FirstTime)
            $this->CustomCheck();
            
          if ($this->IsCompleted()) {
            $this->StoreData();
            $GLOBALS['wizardPage'] = $this->NextWizardPage();
          }  
          else
            $this->DisplayForm();
        }
        
        function IsCompleted() {
          return (!$this->FirstTime && count($this->Errors)<=0);
        }
        
        function CustomCheck() {}
        //abstract
        
        function DisplayForm() {}
        //abstract
        
        function NextWizardPage() {}
        //abstract
        
        function StoreData() {}
        //abstract
        
        function Additional() {
          if ($this->wizardPage) :
        ?>
        <input type="Hidden" name="wizardPage" value="<?php echo $this->wizardPage?>">
        <?php endif;
        }
        
        function Set($Name, $Value) {
          $this->$Name = $Value;
        }
        
        function ErrorReport($Name) {
          if (isset($this->Errors[$Name]))
            printf($this->ErrorMessageFormat, $this->Errors[$Name]);
        }
        
        function GetInitialValue($Name) {
          if (isset($this->Values[$Name]))
            return $this->Values[$Name];
          else
            return false;
        }
        
        function InitialValue($Name) {
          echo $this->GetInitialValue($Name);
        }
      }

    ?>


    One of the key principles in FormProcessor's functionality is that it knows how the HTML form's inputs are named. Later on in this article, I will show how we automate naming of fields, now just take it as it is: FormProcessor's descendants know the name of the array that the form's values are submitted into. Inside the member functions of the class, this name is evaluated as:

    $this->fieldPrefix . $this->Name

    ...where $this->Name is the form's name that we pass as constructor's parameter. $this->fieldPrefix is defined as a data member of the class, but you can think of it as of a constant value that remains the same throughout lifetime of instances of the class. Its only purpose is to transparently add 'uniqueness' to the field names, so that they do not accidentally get mixed with some of the program's other objects.

    The first thing the generic constructor does is it 'smells the air around'. It assigns the global variable (whether it is set or not) with this magic name to $this->Values. Then, if $this->Values is not empty (i.e. form's fields were submitted before) FormProcessor decides that it is the not the first time this form is on the arena. In this case, it calls the abstract $this->CustomCheck() member function.

    Overriding this function in sub-classes allows these classes' authors to implement whatever custom conditions checking they fancy. Of course, being a member function of the class gives CustomCheck() access to $this->Values array, which contains all values that form is working with as an associative array.

    If overridden CustomCheck() finds error(s) that should not allow the form to be considered as completed, it should write error messages in $this->Errors data member. It is also treated as an associative array with the same association as $this->Values. In other words, each submitted value has a potential error message linked with it, which, if not empty, indicates a fault in this value.

    Then, and this is my favorite thing about abstract generic classes, the rest of constructor reads like English: if the form is completed, let's somehow store the data it has. Otherwise, let's display it (again or for the first time - IsCompleted() returns 'false' if this is the form's first time).

    Of course, StoreData() and DisplayForm() are calls to abstract member functions that should be overridden in sub-classes. I hope you have noticed that in case the form is completed, besides storing data, the constructor also assigns a new value to the global variable $wizardPage. This action tells the 'runner' - executing environment - what form it should load next (the 'while' loop in runner will make another iteration).

    Can you guess where the next $wizardPage's value comes from? Of course, from an abstract function that should get overridden in a sub-class.

    The meaning of the rest of the FormProcessor's machinery should become clear from the following discussion, and now, before we attempt to build something useful with our class, I have to explain how the HTML form's inputs know the names they should be assigned.

    More PHP Articles
    More By Yuri Makassiouk


     

    PHP ARTICLES

    - Making Usage Statistics in PHP
    - Installing PHP under Windows: Further Config...
    - File Version Management in PHP
    - Statistical View of Data in a Clustered Bar ...
    - Creating a Multi-File Upload Script in PHP
    - Executing Microsoft SQL Server Stored Proced...
    - Code 10x More Efficiently Using Data Access ...
    - A Few Tips for Speeding Up PHP Code
    - The Modular Web Page
    - Quick E-Commerce with PHP and PayPal
    - Regression Testing With JMeter
    - Building an Iterator with PHP
    - PHP Frontend to ImageMagick
    - Using PEAR's mimeDecode Module
    - Incoming Mail and PHP






    © 2003-2008 by Developer Shed. All rights reserved. DS Cluster 4 hosted by Hostway
    Stay green...Green IT