Creating Complex, Secure Web Forms with PHP and HTML_QuickForm2
Although most developers will admit to lacking artistic talent, we tend to spend much more time on website aesthetics than on writing solid, secure code. Of course, users want visually pleasing websites but this tendency to dwell on appearance often distracts Web developers from other important tasks such as usability and security. Yet neglecting to properly address usability and security concerns can have just as pronounced an effect on a website's success as having a slick logo and layout.
In particular, if your users are unable to effectively participate in your online community because either a Web form is unusable or an attacker used a cross-site scripting attack to shut down a forum altogether, your site users will almost certainly lead an immediate and dramatic exodus to the competition.
For PHP developers, HTML_QuickForm2 PEAR package provides a programmatic interface for rigorously defining form controls, value requirements, and user notifications. Using HTML_QuickForm2 helps these developers create usable and secure Web forms without sacrificing visual appeal. This solution takes much of the guesswork out of secure forms development, allowing you to create robust forms with minimal time investment.
In this article, I show you how to take advantage of HTML_QuickForm2 to streamline the creation and validation of complex HTML forms.
HTML_QuickForm 2 is a PEAR package, meaning you can install it using the PEAR package installer (if you're running PHP 5.3+, learn more about the new installer here). Presuming you're using the original installer, execute the following command to install HTML_QuickForm2:
%>pear install --onlyreqdeps HTML_QuickForm2-alpha
When installed, you can begin programmatically creating your forms.
Creating a Form with HTML_QuickForm2
HTML_QuickForm2 is the second incarnation of the aptly-named HTML_QuickForm, rewritten from the ground up to take advantage of the object-oriented (OO) features in PHP 5. Therefore, if you're not familiar with the OO development approach, it will take some time to get acquainted with the syntax because forms are created using a rigorous class structure.That being the case, I'd like to begin by showing you not one but two examples that hopefully will help elucidate how you can use HTML_QuickForm2 is to create increasingly complex forms. Let's start with one of the simplest possible examples, depicted in Figure 1.
Figure 1. Creating a Simple Form with HTML_QuickForm2
The form in Figure 1 can be created using approximately 25 lines of code, as shown below. Take a moment to review this listing, after which I'll highlight some of the key syntax.
<?php require_once "HTML/QuickForm2.php"; require_once 'HTML/QuickForm2/Renderer.php'; $format = array( '' => 'Newsletter Format:', 'text' => 'Text', 'html' => 'HTML' ); $form = new HTML_QuickForm2('newsletter'); $name = $form->addText('name')->setLabel('Your Name:'); $email = $form->addText('email')->setLabel('Your E-mail Address:'); $newsletter = $form->addSelect('format', null, array('options' => $format)); $newsletter->setLabel('Preferred Newsletter Format:'); $form->addElement('submit', null, 'Submit!'); $renderer = HTML_QuickForm2_Renderer::factory('default'); echo $form->render($renderer); ?>
As you can see, HTML_QuickForm2 offers a series of methods, which are responsible for creating form controls such as text fields (
addText())and select boxes (
addSelect()). Each of these controls is accompanied by control labels that can be added using the
setLabel() method. Finally, HTML_QuickForm2 gives you the flexibility to render forms using a wide variety of approaches, including using the Smarty templating engine and an
HTML_QuickForm2_Renderer object. You can just use the default renderer as demonstrated here, passing that object to the
render() method in order to output the form.
Next, let's consider the slightly more complex example depicted in Figure 2.
Figure 2. Creating a More Complex Form Variation
This time, we're using the fieldset tag to create a slightly more organized form structure. Because the form elements appear inside the fieldset boundary, you need to create these elements using the methods exposed through the fieldset object! Neglecting to do so will cause form elements to be rendered outside of the boundary. The following listing creates the form presented in Figure 2.
<?php require_once "HTML/QuickForm2.php"; require_once 'HTML/QuickForm2/Renderer.php'; $format = array( '' => 'Newsletter Format:', 'text' => 'Text', 'html' => 'HTML' ); $form = new HTML_QuickForm2('newsletter'); $fieldSet = $form->addFieldset()->setLabel('Subscribe to the Newsletter!'); $name = $fieldSet->addText('name')->setLabel('Your Name:'); $email = $fieldSet->addText('email')->setLabel('Your E-mail Address:'); $newsletter = $fieldSet->addSelect('format', null, array('options' => $format)); $newsletter->setLabel('Preferred Newsletter Format:'); $fieldSet->addElement('submit', null, 'Submit!'); $renderer = HTML_QuickForm2_Renderer::factory('default'); echo $form->render($renderer); ?>
Try experimenting with creating form controls using the HTML_QuickForm2 object instead of the FieldSet object in order to observe the effects of control location placement.