RE: Re: Form handling

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> -----Original Message-----
> From: Manuel Lemos [mailto:mlemos@xxxxxxx]
> Sent: 11 June 2009 07:21
> To: Eddie Drapkin
> Cc: PHP General Mailing List
> Subject:  Re: Form handling
> 
> Hello,
> 
> on 06/10/2009 03:10 PM Eddie Drapkin said the following:
> > I've been charged with writing a class that handles forms, once they've
> been
> > POSTed to.  The idea of the class is to handle the most common use-cases
> of
> > POST forms, and any special functionality can be handled with a child
> class
> > at a later date, but for our uses, we're going to have mostly pretty
> typical
> > POST forms.  Follows is the list of cases I've determined that are the
> most
> > common, can anyone think of any that are omitted or that are never going
> to
> > be used?
> >
> > class form_handler {
> >     public /* bool */ function setRequiredFields(array $fields); //takes
> a
> > simple array that corresponds to a $_POST key, verifying that there is
> data
> > on required fields but not for optional fields, returns true or false on
> > error
> >     public /* bool */ function setRequiredFieldTypes(array $fieldTypes);
> > //array of field names => type a la ('username' => array(regex,
> > '/a-zA-Z0-9\-_/'))
> >                 //or 'phone_number' => (array('int', 'min_len' => 7,
> > 'max_len' => 10)) etc, the exact spec is obviously nowhere near done but
> > will probably just wrap a lot of filter_ functions, returns true or
> false on
> > error
> >     public /* string */ function validateAndCaptureError(); //returns
> error
> > or empty string
> >     public /* void */ function validateAndForwardTo($page); //forwards
> to
> > page on error, or not
> > }
> >
> > each of the globule setters will have a corresponding appendRequired...
> > method, so as not to require handling enormous data structures for
> > conditional form building.
> > ♦
> > As you can see, the class looks pretty barren, but I can't think of any
> more
> > functionality than would be required, although I am kickign the idea
> around
> > of having very specific validation type methods ie.
> > form_handler::requireInt($field, array $options) or
> > form_handler::requireRegex($field, $regex), etc.
> >
> > Thoughts?
> 
> You may want consider not reinventing the wheel.
> 
> I use this popular forms generation and validation class since about 10
> years now. It can deal with pretty much all you need now and probably
> later.
> 
> http://www.phpclasses.org/formsgeneration
> 
> Here are some live examples of the class and its plug-ins.
> 
> http://www.meta-language.net/forms-examples.html
> 
> --
> 
> Regards,
> Manuel Lemos

Whilst Manuel's Forms Generation class / Zend Form et al are certainly quick and easy to integrate, if this is an in-house project, I don't see a problem with rolling your own Forms class designed to simply automate some of the common functionality your developers use. In a lot of cases, out-of-the-box classes come with bloat while being all things to all men, which is not a bad thing, per se, but needs to be weighed up when selecting a methodology.

To answer your original question, though, our in-house framework has a base Form class, which is extended through child classes, as well as a base input class, which is extended with child classes such as TextInput, SelectInput etc. This allows each input to have its individual validate() methods, as well as creating a wrapper Form::validate() method which loops through the Input::validate() methods.

Example

$Form		= new Form;
$Form->fields['text']	= new TextInput;
$Form->fields['select']	= new SelectInput;
$Form->fields['select']->options	= array('foo' => 'bar', 'wom' => 'bat');

With regard your setRequiredFields(), we use an Input::$mandatory property, which the Input::validate() method checks.
The setRequiredFieldTypes() is dealt with by the actual File class.
I would certainly separate out the required validation as mentioned with requireInt/Regex methods, which would allow combining of required conditions. We use a $validation bitwise property in the Input class combined with class constants, as well as minlength / maxlength properties for text / password fields.

Other things to consider

- Some method of storing user messages during validation which can be output later.

- Creating an output method for the fields. Repopulating the fields with submitted values, using CSS to highlight missing or invalid fields or creating "custom" fields (such as a date input with a calendar / made up of Y/M/D select inputs) can lead to a mess if you are hardcoding the output. 
For example:

$Form->fields['text']->add_css_class('missing_mandatory');
$Form->fields['text']->set_value('Foo');
$Form->fields['text']->output();

Something further to consider would be to have a $value property and use __set() overloading (http://us3.php.net/manual/en/language.oop5.overloading.php) to validate
Eg 
$Form->fields['select']->value = 'foo'; // Sets value to foo
$Form->fields['select']->value = 'No such option'; // Does not set

- A method / property to check whether the form has been submitted.
If you have a Form::id property, you can pass this through in a hidden field and create a method which checks for the presence of this in the $_POST array.
Example

class Form {
  public $id;
  public $form_id_key = 'my_form_id';

  public /* bool */ function has_been_submitted() {
    $submitted = false;
    
    if (array_key_exists($this->form_id_key,$_POST) &&
        $_POST[$this->form_id_key] == $this->id) {
      $submitted = true;
    }
    
    return $submitted;
  }
}

$Form->id = 'myform';
if ($Form->has_been_submitted()) {
  // Process the form
}

[snip]

<form method='post' action=''>
  <input  type = 'hidden' 
          name = '<?php echo $Form->form_id_key ?>' 
          value= '<?php echo $Form->id ?>' />
</form>

It would be worth thinking about how to handle cases where a Form id is null when checking for submission.


Finally, if the class starts out looking barren, that's not a problem - there's always room to expand if more functionality is needed. Filling a class with functionality you might need, without where and when you'll need it, or how you expect to use it is a Bad Thing.


Apologies all for the essay, but hopefully it's of some use.
Dajve

----------------------------------------------------------------------------
for (thoughts, ramblings && doodles) {
  goto http://dajve.co.uk ;
}



-- 
PHP General Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php



[Index of Archives]     [PHP Home]     [Apache Users]     [PHP on Windows]     [Kernel Newbies]     [PHP Install]     [PHP Classes]     [Pear]     [Postgresql]     [Postgresql PHP]     [PHP on Windows]     [PHP Database Programming]     [PHP SOAP]

  Powered by Linux