Phorms: a PHP form library

Phorms is a general purpose, easy-to-use HTML forms library. Phorms aims to provide a simple framework for generating complex forms.

Forms are created by extending the abstract Phorm class. Validation is simple and easy to implement. Django users especially will find Phorms’ validation familiar:

function required($value)
  if ($value == '' || is_null($value))
    throw new ValidationError('This field is required.');
class CommentForm extends Phorm
  protected function define_fields()
    // Define form fields
    $this->post_id = new HiddenField(255);
    $this->first_name = new TextField("First name", 25, 255, array('required'));
    $this->last_name = new TextField("Last name", 25, 255, array('required'));
    $this->email = new EmailField("Email address", 25, 255, array('required'));
    $this->url = new URLField("Home page", 25, 255);
    $this->number = new IntegerField("Favorite number", 7, array('required'));
    $this->message = new LargeTextField('Message', 5, 40, array('required'));
    $this->notify = new BooleanField('Reply notification');
    // Add some help text
    $this->notify->set_help_text('Email me when my comment receives a response.');
    $this->email->set_help_text('We will never give out your email address.');

Setting default values is simple:

$form = new CommentForm(Phorm::POST, true, array('post_id'=>42, 'notify'=>true));

And form validation is a breeze:

$valid = $form->is_valid();

Phorm instances serialize to an HTML table and provide methods to open and close the form:

echo $form->open($_SERVER['PHP_SELF']);
echo $form;
echo $form->close();

The Phorms library:

You can download it from my projects page or directly.

Update: fixed a couple bugs and put API docs online.

17 thoughts on “Phorms: a PHP form library

  1. Pingback: Phorms: a PHP form library | Artful Code « DevEzine

  2. Pingback: Recommened PHP articles to improve your programming skills! |

  3. And how will I add an option-group with radio-buttons? It look likes it isn’t implemented… please more information about this feature?

    • Sorry it took so long for me to reply. It has been a busy few weeks at work. There is not an option-group with radio buttons. It is simple to implement, however.

      You can copy the OptionGroupWidget source (widgets.php) and change the line in the `serialize` method:

      $option = new CheckboxWidget …


      $option = new RadioWidget…

      And save it as a RadioOptionGroupWidget or similar.

  4. there is a bug in OptionsField class:

    public function get_widget()
    return new OptionGroupWidget($this->options);

    must be:

    return new OptionGroupWidget($this->choices);

    There is no “RadioGroupWidget” i implemented that:
    class RadioGroupWidget extends PhormWidget
    * The options for this field as an array of actual=>display values.
    private $options;

    * @author Jeff Ober
    * @param array $options the options as an array of actual=>display values
    * @return null
    public function __construct(array $options)
    $this->options = $options;

    * @author Jeff Ober
    * @param array $value an array of the field’s values
    * @param array $attributes key=>value pairs corresponding to HTML attributes’ name=>value
    public function html($value, array $attributes=array())
    if (is_null($value)) $value = array();

    foreach ($attributes as $key => $val)
    $attributes[htmlentities( (string)$key )] = htmlentities( (string)$val );

    return $this->serialize($value, $attributes);

    * Returns the field as serialized HTML.
    * @author Jeff Ober
    * @param mixed $value the form widget’s value attribute
    * @param array $attributes key=>value pairs corresponding to HTML attributes’ name=>value
    * @return string the serialized HTML
    protected function serialize($value, array $attributes=array())
    $html = “”;
    foreach ($this->options as $actual => $display)
    $option = new RadioWidget( in_array($actual, $value) );
    $html .= sprintf(‘%s %s’, htmlentities($display), $option->html($actual, $attributes));

    return $html;

  5. Pingback: Christian Krause - view it, code it, share it!

  6. I’m writing an extented version of phorms.
    It is based on git version of phorms
    I supports non-table form (full css), client-side validation (javascript) and I’ll implement fieldsets.

    It is still a work in progress but I hope I could be able to release a first beta version soon !

  7. Is there a supported way to make a file upload field optional?
    If the user don’t upload a file, phorms complains, I tried to change it, but keep getting warnings in getimagesize because i don’t throw an exception when there is no file uploaded.

    By the way excellent work!!!

  8. Hi, I tried the example_form.php after extracting the phorms tarball, but I’m getting the following error on instantiating the HiddenField class:
    “Catchable fatal error: Argument 1 passed to HiddenField::__construct() must be an array, integer given, called in … \htdocs\phorms\examples\comment_form.php on line 18 and defined in … \htdocs\phorms\src\fields.php on line 569″.
    Indeed an integer (255) is given as argument on line 18 in the comment_form.php script. How to solve it?
    Many thanks in advance!

  9. I have found the following bug:
    fields.php line 540, the string should be quoted using double quote instead of single quote
    This leads to incorrect error message when having input with length greater than the required max_length.

  10. Cool library! Thanks for making it, it saves a lot of trouble when you fall back to not using a php-framework for a change. Great fun to use different libraries, and I use yours for forms.

    Something that would be cool too is supporting HTML5, seeing as it is getting bigger and bigger. The way I work around it at the moment is changing the serialize function of a text-field for example, to:

    protected function serialize($value, array $attributes=array())
    $attributes['type'] = (!isset($attributes['type'])) ? 'text' : $attributes['type'];
    return parent::serialize($value, $attributes);

    Note the place where ‘type’ is set. This used to be:

    $attributes['type'] = 'text';

    This meant that whatever type you gave in the definition of the field, it would still use ‘text’. Now you can override it if needed.

    The update of the library that I have in mind would be to alter it to check if HTML5 is supported and use the HTML5 attributes. ‘required’ would be a great one to support too.

    Thanks again!

  11. Hi,

    This lib is great. But I was wondering is there anyway I can inject the field definitions at run time instead of having to define them in the protected define_fields() method?

    I ask because I’m using it for a registration form. Now I’d like to use that form for another country that has 90% common fields but some new ones specific to the country. I’d like to be able to add or remove the fields I need or don’t need but only have one copy of the RegistrationForm class.


  12. Hi there, good work…

    I have identified a bug with hidden fields.. The HiddenField constructor calls its parent but the parameters are in the the wrong order. Validators should be 4th not 3rd..

    Nice work again :)

Leave a Reply

Your email address will not be published. Required fields are marked *


You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>