Page 1 of 4

What do you guys think of Zend_Validate?

Posted: Thu Mar 29, 2007 5:39 pm
by Luke
I'm not so sure I like it. Do you really have to validate() every value? I would prefer an interface more like this:

Code: Select all

$validator = new Zend_Validate;
$validator->add('username', $_POST['username'], new Zend_Validate_NotEmpty(), 'Username is required');
$validator->add('username', $_POST['username'], new Zend_Validate_StringLength(5,15), 'Username must be between 5 and 15 characters');
$validator->add('username', $_POST['username'], new Zend_Validate_Alnum, 'Username must be alpha-numeric');

$validator->add('password', $_POST['password'], new Zend_Validate_NotEmpty(), 'Password is required');
$validator->add('password', $_POST['password'], new Zend_Validate_StringLength(6), 'Password must be at least 6 characters');

if (!$validator->isValid())
{
    foreach ($validator->getErrors() as $error)
    {
        $this->_view->setFormError($error->getId(), $error->getMessage());
    }
}
Their interface appears that you have to run an if ($validator->validate()) for EVERY single thing you want validated. That's stupid. :? :(

EDIT: I was really hoping that this would eliminate my need to use HTML_QuickForms but I really doubt that it will.

Re: What do you guys think of Zend_Validate?

Posted: Thu Mar 29, 2007 6:30 pm
by dreamscape
I haven't looked at Zend_Validate much, but I'm not really a fan of complex interfaces either. I like your idea to validate all that needs validated in one go, but I don't like your interface for adding validators.

Over the past 6 months I've become increasingly attracted to well designed relatively simple fluid interfaces that facade and hide the dirty details of relatively complex interfaces.

Off the top of my head, I would like a validate interface that allows something like (not claiming this is "well designed" since off the top of my head):

Code: Select all

$validate = new Validate($_POST);

$validate->username->isNotEmpty->orError('Username is required');
$validate->username->hasLengthOf(5, 15)->orError('Username must be between 5 and 15 characters');
$validate->username->isAplhaNumeric->orError('Username must be alpha-numeric');
           
$validate->password->isNotEmpty->orError('Password is required');
$validate->password->hasLengthOf(6)->orError('Password must be at least 6 characters');

Posted: Thu Mar 29, 2007 6:55 pm
by Luke
hmm... that's kind of cool. Maybe some day I'll write an input validation library... after the 8 million other things I have on my list

Posted: Thu Mar 29, 2007 7:19 pm
by Christopher
Zend_Validate is just kind of sad ... and it would be a very long (and bitter) post to explain why ... I hope they get there eventually ...


(FYI dreamscape - you have created a fluent version of Zend_Filter_Input 8O )

Posted: Thu Mar 29, 2007 7:37 pm
by Luke
oh well... back to HTML_QuickForms... this is way cooler:

Code: Select all

public function _processDataAdd()
    {
        $form = new HTML_QuickForm('add_calendar');
        
        $title = new HTML_QuickForm_text('calendar_title');
        $form->addElement($title);
                
        $description = new HTML_QuickForm_textarea('calendar_description');
        $form->addElement($description);
                
        $admin_must_allow = new HTML_QuickForm_text('calendar_admin_must_allow');
        $form->addElement($admin_must_allow);
        
        $form->applyFilter('__ALL__', 'trim');
        
        $form->addRule('calendar_title', 'This is required', 'required');
        $form->addRule('calendar_title', 'This cannot be over 100 characters', 'maxlength', 100);
        
        $form->addRule('calendar_description', 'This cannot be over 5000 characters', 'maxlength', 1000);
        
        return $this->_processForm($form);
    }
in a parent controller...

Code: Select all

protected function _processForm(HTML_QuickForm $form, $include_wrap = true)
    {
        if ($form->validate())
        {
            return $form;
        }
        
        $errorPrefix = '';
        $errorSuffix = '';
        
        if ($include_wrap)
        {
            $errorPrefix = '<span class="error">';
            $errorSuffix = '</span';
        }
        
        foreach ($form->_elements as $element)
        {
            $error = $form->getElementError($element->getName());
            if (!empty($error))
            {
                $this->_view->setFormError($element->getName(), $errorPrefix . $this->_view->escape($error) . $errorSuffix);
            }
            $this->_view->setFormValue($element->getName(), $form->exportValue($element->getName()));
        }
        return false;
    }

Posted: Thu Mar 29, 2007 7:49 pm
by dreamscape
arborint wrote:(FYI dreamscape - you have created a fluent version of Zend_Filter_Input 8O )
Didn't they recently remove Zend_Filter_Input ?

Posted: Thu Mar 29, 2007 8:18 pm
by Begby
I have a validator I wrote awhile back that uses a validation delegate you add to a model then a validateable interface, you use it like this...

Code: Select all

$model = someClassThatImplemetsValidateable()

$model->fieldName()
->Validator()
 ->required
 ->minLength(10)
 ->isAlpha
 ->errorMsg('Field must be at least 10 characters long and alphanumeric') ;

$model->password()
->Validator()
  ->matches('passwordVerify')
  ->errorMsg('Passwords must match') ;
  ->onInsert()
    ->required
    ->minLength(5)
    ->errorMsg('Password is required and must match') ;

if (!$model->validate(Validator::ON_INSERT))
{
  $errors = $model->getErrors() ;
}

Posted: Thu Mar 29, 2007 9:19 pm
by Benjamin
I prefer to just write my own validation using isset and regex expressions. I can't imagine instaniating a new class multiple times for every field I want to validate.

Validation is probably one of the most time consuming aspects of developing a particular page so I understand why everyone wants to find a faster way to do it. To solve this problem I wrote a class that will look at a database table and spit out validation for all the fields.

Then it's just a matter of tweaking each field a bit rather than writing it from scratch each time. Saves loads of time.

Posted: Thu Mar 29, 2007 9:45 pm
by Christopher
The Ninja Space Goat wrote:oh well... back to HTML_QuickForms... this is way cooler:
The main problem between Quick Forms and other monolithic solution is the hard coding of rules. This is handy for the easy stuff, but in the long run atomic rules and filter (like ZF now had) are much more extensible. Real difference is that instead of referencing internal rules like this:

Code: Select all

$form->addRule('calendar_title', 'This cannot be over 100 characters', 'maxlength', 100);
You provide external rules like this:

Code: Select all

$form->addRule('calendar_title', new Rule_Maxlength('This cannot be over 100 characters', 100));
Fairly trivial difference from the code point of view, but think of the extensibility. Now I want a rule that verifies credit card numbers or looks up SKUs to see if a valid one was entered, etc. etc. etc. Atomic rules are superior in my book.

Also, if you look at your code it is really a controller. That is where ZF has the mix confused. FilterChain and Validator classes are really designed to be used by a Form Controller class as building blocks. So instead of the monolithic Quick Forms style, you now have a number of modular classes that can be used separately or in combination.

Posted: Thu Mar 29, 2007 9:54 pm
by Luke
I agree 100%. That's why I want to be rid of HTML_CrapForms, but so far I've yet to find anything with an quicker/easier interface.

Another thing I don't like about HTML_QuickForms is that the relationship between validation and form display is too tight. I don't even use the renderers in HTML_QuickForms. I don't want my forms library to render my form... I'll write the form myself. I'm sure some people would like that ability, but I have tried to come up with an interface that allows both validation as well as rendering of a form, and there really just isn't any good way to do that. Seperate the two completely... that's the only way.

Posted: Fri Mar 30, 2007 3:09 am
by Maugrim_The_Reaper
Zend_Validate is very nice as a base object upon which to base the "real" validator. By itself it's almost pathetic. My main gripe is that PHP is already infamous for its insecurity (fact is you can't trust even yourself with PHP ;)), and a 1.0 release of the Zend Framework with this level isn't helping anyone. It should be simple to use, not obviously such a badly chained task you'll be tempted to find alternatives for (and we all know we've each been looking at alternatives).

It would be a positive boon to have some higher level elements before calling something 1.0 - since 1.0 will inevitably focus a lot of public attention. I've already stated elsewhere that there's an "expectation gap" for 1.0 though. The version number has nothing to do with completion (not a whit!), all it means is that Zend will undertake a commitment to a stable API. The "gap" is that most people will assume it means completion - their expectations differ from the framework developers. Of course it can't be complete - components are still in the Incubator, there are tons of outstanding proposals, AFAIK there's been little focused optimisation (premature optimisation is no longer premature when a class component is complete for crying out loud), documentation remains basic.

I think it's worth pointing out this is just one isolated complaint - and it's only against one or two component classes. So don't judge the entire framework based on my moaning about one part of it. Although admittedly when I want to change Zend_Uri's behaviour I do sometimes end up in a padded cell tearing my hair out...;). That damn class has static methods littered everywhere... And it can be frustrating questioning someone on performance when they seem puzzled about how you got that funky KCacheGrind snapshot ;).

Posted: Fri Mar 30, 2007 3:35 am
by Christopher
It is just frustrating to see the course these things take. I started pushing for design changes a year ago, and many of them got done. It has been a small but persistent group that has championed what I consider to be best practices. Too small a group and too many other people clamoring for more statics, more procedural-style designs, etc. The changes I am talking about are the MVC changes to the controllers, adding request/response objects, getting a normal registry, dumping Zend.php, etc. etc.

I proposed fairly standard filterchain/validator classes way back in June of 2006. But there were few at that time interested in a request container (or any containers) so it just sat there. I kept pestering about the need for something better than Zend_Filter_Input (of which my negative opinion should be well known). But then at some point they did a new filterchain/validator proposal with the main difference that the chains work on individual vars instead of an array or the request object. That makes the filterchain/validator classes essentially useless. Plus the validation rules don't carry error messages so you need a separate system for a main feature of validation.

So we got atomic filters and rules which is a win. Zend_Filter_Input is gone which is a win. But until the filterchain/validator situation is fixed, there will be no good input/form controller that makes it easy to deal properly with all input. And that's not just a design goal -- it is critical for PHP.

Urgh.

Posted: Fri Mar 30, 2007 3:40 am
by neel_basu
I Wanna Say You How asy It Is Zigmoyd Validator Class
----------------------------------------------------------------
Just Write The HTML From and Do This In Php

Code: Select all

<?php
$validate = new validate("get");//if Used new validate() It will detect the form method automatically
echo "<pre>";
print_r($validate->report());//Holds the reports
echo "</pre>";
?>
If You wanna exclude/Make a Form field optional either add a '!' at the form field name e.g. replace form_field_name by !form_field_name or do

Code: Select all

$validate->exclude("form_field_name");

Posted: Fri Mar 30, 2007 4:30 am
by onion2k
The problem with validation classes is that, without exception, they're not powerful enough. If you need to validate content on a contextual basis (eg, if field1 is completed then field2 must be completed, and field3 must be an email address, and field4 must be identical to field3) there's nothing better than a simple if..else tree. Simply checking the values of each individual field meet some requirements is trivial. When you're doing proper validation you invariably need much more than that though.

Posted: Fri Mar 30, 2007 4:38 am
by neel_basu
onion2k wrote:(eg, if field1 is completed then field2 must be completed, and field3 must be an email address, and field4 must be identical to field3)
All What You are trying to do is possible Use Form Field Name

Code: Select all

<input type="text" name="@email" value="<?= $_GET['@email'] ?>" />
Email Validation

Code: Select all

<input type="text" name="Password" value="<?= $_GET['Password'] ?>" />
<br />
  Confirm Password : 
<input type="text" name="^Password" 
value="<?= $_GET['^Password'] ?>" />
Password Confirmation
Use This DTD http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd

Code: Select all

<input type="text" name="+validation" value="" />
I age Validation Field All You have to do is in the HTML form You dont need to do anything on php[/syntax]