HomePHP Page 4 - The Singleton and Factory Patterns in PHP: Working With Singletons
Ending up the coding round: defining the remaining form element classes - PHP
In this fourth part of the series covering the Singleton and Factory Design Patterns in PHP, we will discuss issues stemming from the fact that PHP 4 does not have an abstract class. Since we found it useful in the previous article to define the form element factory class as an abstract class, in this article we will discuss the process for making the form element factory class a Singleton, and how this serves our purposes.
Returning to the list of form element classes, there are still some that need to be defined. So, here are the proper definitions for form buttons, submit buttons and reset controls. Also, text areas and select boxes are included:
// class button class button{ var $html; function button($attributes=array()){ if(count($attributes)<1){ trigger_error('Invalid number of attributes'); exit(); } $this->html='<input type="button" '; foreach($attributes as $attribute=>$value){ $this->html.=$attribute.'="'.$value.'" '; } $this->html.='/>'; } function getHTML(){ return $this->html; } } // class submit button class submitbutton{ var $html; function submitbutton($attributes=array()){ if(count($attributes)<1){ trigger_error('Invalid number of attributes'); exit(); } $this->html='<input type="submit" '; foreach($attributes as $attribute=>$value){ $this->html.=$attribute.'="'.$value.'" '; } $this->html.='/>'; } function getHTML(){ return $this->html; } } // class reset button class resetbutton{ var $html; function resetbutton($attributes=array()){ if(count($attributes)<1){ trigger_error('Invalid number of attributes'); exit(); } $this->html='<input type="reset " '; foreach($attributes as $attribute=>$value){ $this->html.=$attribute.'="'.$value.'" '; } $this->html.='/>'; } function getHTML(){ return $this->html; } } // class textarea class textarea{ var $html; function textarea($attributes=array()){ if(count($attributes)<1){ trigger_error('Invalid number of attributes'); exit(); } $this->html='<textarea '; $textvalue=''; foreach($attributes as $attribute=>$value){ ($attribute!='value')?$this- >html.=$attribute.'="'.$value.'" ':$textvalue=$value; } $this->html=preg_replace("/\"? $/","\">",$this->html); $this->html.=$textvalue.'</textarea>'; } function getHTML(){ return $this->html; } } // class selectbox class selectbox{ var $html; function selectbox($attributes=array()){ if(count($attributes)<1){ trigger_error('Invalid number of attributes'); exit(); } $this->html='<select '; $options=''; foreach($attributes as $attribute=>$value){ if($attribute!='options'){ $this->html.=$attribute.'="'.$value.'" '; } else{ foreach($value as $values=>$label){ $options.='<option value="'.$values.'">'.$label.'</option>'; } } } $this->html=preg_replace("/\"? $/","\">",$this->html); $this->html.=$options.'</select>'; } function getHTML(){ return $this->html; } }
With all of the form element classes listed, we can go ahead and set up an example for rendering form elements, by using the Singleton model of the form factory class. So, let’s begin instantiating an object from the Singleton factory class, and next spawn several form objects. The sample code is as follows:
// get a single instance of the form element factory $formFactory=formElementFactory::getInstance(); // create form objects $textinput=$formFactory->createElement ('textinput',array('name'=>'username','value'=>'', 'maxlength'=>'20')); $radiobutton=$formFactory->createElement ('radiobutton',array ('name'=>'option1','value'=>'1','checked'=> 'true')); $checkbox=$formFactory->createElement ('checkbox',array ('name'=>'option2','value'=>'1','checked'=> 'true')); $textarea=$formFactory->createElement ('textarea',array ('name'=>'comments','rows'=>'20', 'cols'=>'30')); // make array with form objects $formElements=array($textinput,$radiobutton,$checkbox,$textarea); // display form elements foreach($formElements as $element){ echo $element->getHTML(); }
As you can see, an object is instantiated from the factory class, by calling first the “getInstance()” method. Doing so, we’re ensuring that a single instance of the object is created across the snippet, thus the Singleton pattern is properly applied.
Then, some form objects are directly created through the “createElement()” method, as we’ve seen in previous examples. The only thing to note here is that the call to this method is carried out within the object context, that is using the (->) syntax, since now the method is not static. Therefore, the scope resolution operator (::) is not used any longer.
Finally, we make an array with the form objects, which are displayed through a common “foreach” loop.
At this point, we’ve applied both the Singleton and Factory patterns to building web-based forms within a PHP 4 controlled environment. Hopefully, a practical application of these patterns in a real scenario helps to demonstrate how a specific problem can be addressed by using a proven solution.
However, the mechanism for factoring form elements exposes some drawbacks, since the form rendering process is still immature. Definitely, greater control of layout and visual presentation is required.
To wrap up
In the next part of the series, I’ll tackle the issues related to visual presentation and layout of form elements. I will apply what we've learned until now as a starting point for building an extensible form generator class. Probably, you’ll have some time to test your skills by successfully implementing these popular design patterns in your PHP programs.