Sunday
2
May
2010

Validation of two values or how to proove identical-ness

Hy interested ones,

today I integrated two improvements for Zend_Validate_Identical.

Zend_Validate_Identical is a validator which enables you to check if two values are identical.
Values means in this case string, integers, floats, or even objects.

A manual validation would look like this:

$valid = new Zend_Validate_Identical(array('token' => '1234'));
	
if ($valid->isValid($input)) {
    // let's go on
} else {
    // oops... not valid
}

Simple as is…

Now, when $input is the string “1234” we will get true. When it differs we will get false. This means even if we have a integer “1234” the validation will fail. The reason behind this behaviour is that Zend_Validate_Identical does a strict validation including the type of the input.

But sometimes it is wished and necessary to validate only the content regardless of it’s type.
Zend_Validate_Identical supports now also non-strict validation. See the following example:

$valid = new Zend_Validate_Identical(
    array('token' => '1234', 'strict' => false)
);
	
if ($valid->isValid($input)) {
    // let's go on
} else {
    // oops... not valid
}

As you can see the above example is nearly identical to the first example with one difference. We defined the property strict to be false. By using this option we said Zend_Validate_Identical to use non-strict validation.

In this case, when $input is a integer “1234” we will also get true in return and also when it’s a float “1234”.

Now what to do when you want to validate if two form elements are identical. Seems tricky as Zend_Validate_Identical has no connection to Zend_Form, and it would not know which two elements you want to validate.

Easy as is, you can now give the elements name as token which holds the token to validate against. What does this mean? Let’s see a little example:

<?php
error_reporting(E_ALL|E_STRICT);
ini_set('include_path',ini_get('include_path').PATH_SEPARATOR.'../library');
require_once('Zend/Loader/Autoloader.php');
$loader = Zend_Loader_Autoloader::getInstance();
print "<pre>";
	
$request = new Zend_Controller_Request_Http();
	
// setup the form
$form = new Zend_Form();
$form->setMethod(Zend_Form::METHOD_POST)
$form->addElement('password', 'password1');
$form->addElement('password', 'password2', array(
    'validators' => array(
        array('identical', false, array('token' => 'password1'))
    )
));
$form->addElement('submit', 'submit');
	
// check the form
if($request->isPost()) {
    $formData = $request->getPost();
    if($form->isValid($formData)) {
        $form->getValues();
        echo "FORM VALID";
    } else {
        print "\nVALIDATION FAILURE:";
        print_r($form->getMessages());
    }
}
print "</pre>";
?>
<html>
<head>
<title>Test</title>
</head>
<body>
<?php echo $form->render(new Zend_View());?>
</body>
</html>

You can run the above example standalone in your browser. It shows you the behaviour of Zend_Validate_Identical and how to combine it efficent within Zend_Form.

For us the important line is:

$form->addElement('password', 'password1');
$form->addElement('password', 'password2', array(
    'validators' => array(
        array('Identical', false, array('token' => 'password1'))
    )
));

As you see we added the Identical validator to the second element by using the first elements name as token.
This way the value of the first element is compared with the value of the second element.

Simple as is :-)

This is handy when you want to validate two user inputs. For example when your user has to enter his email adress two times to be sure he did not mistype it, or he has to enter the same password two times.

Note that these two described features are available within trunk and as with ZF 1.10.5 and NOT BELOW.

I hope you find this two features useful. More to come soon…

Greetings
Thomas Weidner
I18N Team Leader, Zend Framework

Zend Framework Advisory Board Member
Zend Certified Engineer for Zend Framework

Back to top
  1. uli

    Monday, May 3, 2010 - 10:49:05

    this is a very nice and a long time missing validator, but let’s imagine you’ve got a form and the name of a form element is the same as the string I want to match against. Do you have to rename the form element to get the value matched against the string instead of the form element’s value with the same name? Is it possible to disable the form magic with a flag?

  2. Marcus Stöhr

    Monday, May 17, 2010 - 12:19:36

    Hi Thomas,

    great addition. However, when I try to use it the way you showed it, I always get this error: No token was provided to match against.

    My code looks like the following:

    /** form elements **/
    $password = new Zend_Form_Element_Password(’password1′, array(
    ‘label’ => ‘Passwort:’,
    ‘required’ => true,
    ‘filters’ => array(
    ‘StripTags’
    ),
    )
    );

    $password2 = new Zend_Form_Element_Password(’password2′, array(
    ‘label’ => ‘Passwort wiederholen:’,
    ‘required’ => true,
    ‘validators’ => array(
    array(
    ‘identical’,
    false,
    array(’token’ => ‘password1′)
    )
    )
    )
    );

    I extend the base Zend_Form and add all elements in my own init()-method. Is there anything wrong with this approach?

  3. thomasw

    Monday, May 17, 2010 - 22:08:12

    The used release… try trunk or you have to wait until 1.10.5 has been released

  4. Marcus Stöhr

    Monday, May 17, 2010 - 22:49:05

    Hi Thomas,

    I use the latest version from trunk (1.11.0dev) which you stated in your article. :)

  5. thomasw

    Monday, May 17, 2010 - 23:06:19

    Eighter your extension of Zend_Form is buggy or the used syntax for validators is false.

    You can simply check if it works by executing the example noted in the blog.

    Whatever your problem with Zend_Form is: Please ask within the mailing list for details.

  6. Marcus Stöhr

    Monday, May 17, 2010 - 23:11:41

    Thomas, sorry for the confusion. Your validator works great and I traced the problem down to a issue with the Zend Session resource for Zend Application. After commenting the lines out, it worked.