如何在此Validator之后运行此Filter

jbl*_*lue 6 php zend-framework zend-validate zend-filter

我有一个元素.我想为它添加自定义验证器和自定义过滤器.验证器确保输入是几个允许值之一,然后过滤器将一些自定义值添加到输入.这意味着我必须在运行过滤器之前先验证原始输入.我是按照这个顺序做的

$element = new Zend_Form_Element_Text('element');
$element->addValidator('PermittedValue', false);
$element->addFilter('TotalHyphen', false);
$this->addElement($element);
Run Code Online (Sandbox Code Playgroud)

但这个顺序没有得到尊重.过滤器首先运行并更改数据,然后验证器在过滤的数据上运行,这意味着即使对于有效输入它也总是失败.从文档中可以看出这是故意的

注意:验证在过滤值上运行Zend_Form_Element :: isValid()在验证之前通过提供的过滤器链过滤值.有关更多信息,请参阅过滤器部分.

如何指定验证器和过滤器的运行顺序?

Dav*_*aub 7

当然,似乎要创建一个支持后验证过滤的自定义元素.这个怎么样:

/**
 * An element that supports post-validation filtering
 */
class My_Form_Element_PostValidateFilterable extends Zend_Form_Element_Text
{
    protected $_postValidateFilters = array();

    public function setPostValidateFilters(array $filters)
    {
        $this->_postValidateFilters = $filters;
        return $this;
    }

    public function getPostValidateFilters()
    {
        return $this->_postValidateFilters;
    }

    public function isValid($value, $context = null)
    {
        $isValid = parent::isValid($value, $context);
        if ($isValid){
            foreach ($this->getPostValidateFilters() as $filter){
                $value = $filter->filter($value);
            }
            $this->setValue($value);
        }
        return $isValid;
    }
}
Run Code Online (Sandbox Code Playgroud)

用法是这样的:

$elt = $form->addElement('PostValidateFilterable', 'myElement', array(
     'label' => 'MyLabel',
     'filters' => array(
         'StringTrim',
         // etc
     ),
     'validators' => array(
         'NotEmpty',
         // etc 
     ),
     // here comes the good stuff
     'postValidateFilters' => array(
         new My_Filter_RunAfterValidateOne(),
         new My_Filter_RunAfterValidateTwo(),
     ),
));
Run Code Online (Sandbox Code Playgroud)

这样可以保持表单中的验证和过滤 - 保持控制器很薄.

未经测试,只是在黑暗中刺伤.当然,您可以通过密钥等方式增加/修改API以添加/删除过滤器.

Whaddya认为?