我有一个元素。我想为它添加自定义验证器和自定义过滤器。验证器确保输入是几个允许值之一,然后过滤器将一些自定义值添加到输入。这意味着我必须在运行过滤器之前先验证原始输入。我按此顺序执行
$element = new Zend_Form_Element_Text('element');
$element->addValidator('PermittedValue', false);
$element->addFilter('TotalHyphen', false);
$this->addElement($element);
但这个顺序没有受到尊重。过滤器首先运行并更改数据,然后验证器在过滤的数据上运行,这意味着即使对于有效输入它也总是失败。从documentation看来,这是故意的
注意:验证在过滤时运行 值Zend_Form_Element :: isValid() 通过提供的过滤值 验证前过滤链。看到 过滤器部分了解更多信息 信息。
如何指定验证器和过滤器的运行顺序?
答案 0 :(得分: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;
}
}
用法是这样的:
$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(),
),
));
这样可以保持表单中的验证和过滤 - 保持控制器很薄。
未经测试,只是在黑暗中刺伤。当然,您可以通过密钥等方式增加/修改API来增加/删除过滤器
Whaddya认为?
答案 1 :(得分:4)
也许根本不添加过滤器。首先在控制器中验证内容,然后单独使用过滤器:
$request = $this->getRequest();
if ($request->isPost() && $form->isValid($request->getParams())) {
$filter = new Filter_Whatever();
$val = $filter->filter($request->getParam('element'));
... //call your model or whatever
}
我从来没有这样做过,但我认为这(或类似的东西)可能有用。
答案 2 :(得分:1)
好点! ,
在验证输入之前,应该或必须运行AFAIK过滤器: 来自ZF docs
这通常是有用的和/或必要的 对输入执行一些规范化 在验证之前。例如,你 可能想要删除所有HTML,但是 对剩下的内容进行验证 确保提交有效。要么 你可能想修剪空的空间 周围输入使a StringLength验证器将使用 正确的输入长度没有 计算领先或尾随 空白字符。
但当且仅当你遇到无法解决mingos答案的情况时,必须是帮助
答案 3 :(得分:1)
您希望实现的是更改文本元素处理方式的默认行为。因此,我认为您可以创建自己的元素(例如My_Form_Element_Text),该元素扩展Zend_Form_Element_Text并重载其isValid()方法。
具体来说,您可以在原始的isValid()方法中更改第二行,从$value = $this->getValue();
更改为$value = $this->getUnfilteredValue();
。这样,您的验证将使用未过滤的值执行。