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:

require_once('lib/phorms/phorms.php');
 
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:

  • supports file and image uploads
  • has easy to use validation
  • is extensible by subclassing the build-in PhormField and PhormWidget classes
  • is completely documented with phpdoc

You can download it from my projects page or directly.

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

Leave a comment | Trackback
Apr 13th, 2009 | Posted in Programming, Software
Tags:
  1. Great but, no ButtonField?
    Jun 5th, 2009 at 17:28 | #1

    I really like your code.
    Do I need to write my own ButtonField class?

  2. Jeff
    Jun 8th, 2009 at 06:51 | #2

    Yes. Take a look at the code for HiddenField; it is a good example of extending the TextField class.

  3. bert oost
    Aug 19th, 2009 at 03:14 | #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?

    • Sep 2nd, 2009 at 12:14 | #4

      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 …

      to:

      $option = new RadioWidget…

      And save it as a RadioOptionGroupWidget or similar.

  4. Oct 1st, 2009 at 09:41 | #5

    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. required
    Nov 18th, 2009 at 02:14 | #6

    looks like django forms

  6. Nov 18th, 2009 at 02:40 | #7

    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. Cesar
    Dec 6th, 2009 at 03:38 | #8

    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. Zeff
    Dec 26th, 2009 at 04:15 | #9

    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!
    Zeff

  9. benson
    May 30th, 2010 at 11:08 | #10

    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. Mosselman
    Reply | Quote
    Aug 18th, 2011 at 13:32 | #11

    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. Reply | Quote
    May 7th, 2012 at 12:00 | #12

    Photography http://ojyedamekub.de.tl sexy preteen nudity lol Kitten is hella funny!! n she loves dick dasa plus lol bt yea i smack up kittens pussy ne day of the week