Interactive PHP CLI Applications using Zend Form

Over the weekend, I was toying with the idea of interactive cli applications using readline() and Zend Form for validating input. My motivation for using Zend Form or rather Zend Form elements was to exploit the power of features such as labels, validators, filters and the prospect of reusing forms within web application code.

First step was creating a simple filter that converts validation errors to a string

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
<?php
 
class Filter_FormErrors implements Zend_Filter_Interface
{
/**
* Filter method
*
* @param array $errors
* @return string
*/
public function filter($errors) {
if (!is_array($errors)) {
$errors = (array)$errors;
}
$flatten = array();
array_walk_recursive($errors, function($value, $key) use (&$flatten) {
$flatten[] = $value;
});
$message = implode(', ', $flatten);
return $message;
}
}
view raw FilterFormErrors.php hosted with ❤ by GitHub

Next was creating a class that wraps the readline() function and logic for prompting the user for valid input as long as the input remains invalid (See the article PHP CLI Colors – PHP Class Command Line Colors for outputting colours in CLI).

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
<?php
 
class Cli_Prompt
{
/**
* @var Zend_Form
*/
protected $_form = null;
/**
* Prompt constructor
*
* @param Zend_Form $form
*/
public function __construct(Zend_Form $form) {
if (php_sapi_name() !== 'cli') {
throw new RuntimeException('Class can only be used from the command line');
}
$this->_form = $form;
}
/**
* Prompts the user for input and validates the input
*
* @return Zend_Form
*/
public function prompt()
{
$elements = $this->_form->getElements();
$errorFilter = new Filter_FormErrors();
$colour = new Cli_Colour();
foreach ($elements as $element)
{
$firstRun = true;
$element instanceof Zend_Form_Element;
while (!$element->isValid($element->getValue())) {
$label = '';
if (!$firstRun) {
$label = $element->getLabel() .
' (Error: ' . $colour->getColoredString(
$errorFilter->filter($element->getMessages()) , 'red', 'light_gray') .
'): ';
} else {
$label = $element->getLabel() . ': ';
$firstRun = false;
}
$input = readline($label);
$element->setValue($input);
}
}
return $this->_form;
}
}
view raw CliPrompt.php hosted with ❤ by GitHub

And a few lines to test the code:

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35
<?php
 
$form = new Zend_Form();
$form->setElements(array(
new Zend_Form_Element_Text('colour', array(
'required' => true,
'label' => 'Please enter acceptable colours (blue, green or red)',
'validators' => array(
array('NotEmpty', true, array(
'messages' => 'A colour is required'
)),
array('InArray', true, array(
'messages' => 'Colour is uncceptable',
'haystack' => array('blue', 'green', 'red')
))
)
)),
new Zend_Form_Element_Text('someOtherInput', array(
'required' => true,
'label' => 'Please enter acceptable words (thank, you)',
'validators' => array(
array('NotEmpty', true, array(
'messages' => 'A word is required'
)),
array('InArray', true, array(
'messages' => 'Word is uncceptable',
'haystack' => array('thank', 'you')
))
)
))
));
 
$prompt = new Cli_Prompt($form);
$prompt->prompt();
//now we may do other stuff as we are guaranteed to have valid input
view raw CliApp.php hosted with ❤ by GitHub

Here’s what my output looks like

 

Leave a comment ?

16 Comments.

  1. Simple interactive #php CLI Applications using #zend Form http://t.co/OJgqxiWK

  2. Very nice. One practical use for zend form (I’m not sure about actually using them in a website :P )

  3. I am not sure how usefull this is, but do you know you can use providers to make cli tools very easy.

    • I know providers can be used to create cli tools (although it didn’t quite cross my mind when playing with this) but my focus here was more about leveraging features in zend form rather than the framework for the cli tool. Thanks nonetheless, you’ve just given me an idea for my next article…

  4. Interactive PHP CLI Applications using Zend Form – http://t.co/nRxXDrwa

  5. Or you could simply use the Symfony 2 Console Component, which does everything listed here and more.

    Cheers.

  6. Bart Stavenuiter

    You could also use zend validate input, which is faster to load, but has some differences to zend form.

  7. Vladislav Veselinov

    That’s cool on so many levels :)

  8. Interactive PHP CLI Applications using Zend Form | http://t.co/zT0OgG79 #weblabor

  9. Zend_form prezentációk , cikkek | Kerek egy ég alatt - pingback on February 17, 2012 at 9:03 pm
  10. Interactive PHP CLI Applications using Zend Form | http://t.co/Qu5peBSh via @ojenikoh

  11. Interactive #PHP CLI Applications using #Zend Form | http://t.co/BgIvxDx9

Leave a Comment

NOTE - You can 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> <pre lang="" line="" escaped="" highlight="">