Home arrow PHP arrow Page 4 - Making PHP Forms Object-Oriented
PHP

Making PHP Forms Object-Oriented


In this article Yuri explains an object oriented way to create and use forms on your web site.

Author Info:
By: Yuri Makassiouk
Rating: 4 stars4 stars4 stars4 stars4 stars / 40
January 23, 2003
TABLE OF CONTENTS:
  1. · Making PHP Forms Object-Oriented
  2. · Analysis
  3. · Executing Environment
  4. · Implementing the FormProcessor Class
  5. · Inputs - Brief Introduction
  6. · Example of a Form
  7. · Conclusion

print this article
SEARCH DEVARTICLES

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.
blog comments powered by Disqus
PHP ARTICLES

- Removing Singletons in PHP
- Singletons in PHP
- Implement Facebook Javascript SDK with PHP
- 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

Watch our Tech Videos 
Dev Articles Forums 
 RSS  Articles
 RSS  Forums
 RSS  All Feeds
Write For Us 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Contact Us 
Site Map 
Privacy Policy 
Support 

Developer Shed Affiliates

 




© 2003-2017 by Developer Shed. All rights reserved. DS Cluster - Follow our Sitemap
Popular Web Development Topics
All Web Development Tutorials