phparrayszend-validatezend-filter

Zend_Filter_Input with Zend_Validate_InArray-Validator which has an array as its needle


I'm using Zend_Filter_Input to filter and validate my data. For a field (gender), I am using the Zend_Validate_InArray to validate, if the value is in

array('m', 'w');

So far so good.
While running my UnitTests, I noticed, that an empty array is a valid value for gender, too.
To analyze this, I wrote the following code:

$genderArray = array('m', 'w');
$needle = array();
if(in_array($needle, $genderArray)) {
    Zend_Debug::dump('is in array');
} else {
    Zend_Debug::dump('is not in array');
}

$validator = new Tueks_Validate_InArray($genderArray);
if ($validator->isValid($needle)) {
    Zend_Debug::dump('is in array');
} else {
    Zend_Debug::dump('is not in array');
}

Both times, I got 'is not in array'.

But when I use the following code:

$child = new Tueks_Placereport_Child();
$child->setGender($needle);
$child->validate();

everything works fine (--> array() ist part of array('m', 'w'))?!?

Here is the relevant part from my validate-method:

$genderArray = array('m', 'w');
$filters = array();
$validators = array('gender'=> 
                     array('presence'=> 'required',
                           new Tueks_Validate_InArray($genderArray)
                          )
                   );
$input = new Zend_Filter_Input($filters, $validators, $this->_data);

Tueks_Validate_InArray is the same like Zend_Validate_InArray, but with other messages. I don't see the problem, why, when using Zend_Filter_Input, an empty array is a valid value. Hope you can help me.


Solution

  • This actually is a bug in Zend Framework thas has not been fixed as of yet. And as Zend_Filter_Input has been discontinued with Zend Framework 2, I'll highly doubt that it will ever be. However, there is a patch attached to the ticket that should resolve this issue.

    I also did a little debugging and could track it down to the method _validateRule in Zend_Filter_Input:

    There you can find this code block:

    if (!is_array($field)) {
        $field = array($field);
    }
    [...]
    foreach ($field as $key => $value) {
    [...]
        if (!$validatorChain->isValid($value)) {
    

    $field contains the value of the field. As you can see, if you pass a non-array value, it is put into an array, so that the foreach block is entered. However, if you pass an empty array, then $field will stay array(0) {} and therefore the whole foreach block will not be entered. Therefore not a single validation (nor a non-empty check) will be exectued.

    I also tried to find a workaround, but they are all rather awkward. Therefore, the most simple workaround for this would be to check if $value is an empty array.