如何让这个过滤器在这个验证器之后运行

发布于 2024-10-14 20:02:19 字数 633 浏览 3 评论 0原文

我有一个元素。我想向其中添加自定义验证器和自定义过滤器。验证器确保输入是多个允许值之一,然后过滤器向输入添加一些自定义值。这意味着我必须在运行过滤器之前首先验证原始输入。我按照这个顺序执行

$element = new Zend_Form_Element_Text('element');
$element->addValidator('PermittedValue', false);
$element->addFilter('TotalHyphen', false);
$this->addElement($element);

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

注意:验证在过滤后进行 值 Zend_Form_Element::isValid() 通过提供的过滤值 验证之前的过滤器链。看 过滤器部分了解更多 信息。

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

I have an element. I want to add a custom validator and custom filter to it. The validator makes sure the input is one of several permitted values, then the filter adds some custom values to the input. This means I have to validate the original input first before running the filter. I do it in this order

$element = new Zend_Form_Element_Text('element');
$element->addValidator('PermittedValue', false);
$element->addFilter('TotalHyphen', false);
$this->addElement($element);

but this order isn't being respected. The filter runs first and changes the data, then the validator runs on the filtered data which means it always fails even for valid input. It seems from documentation that this is intentional

Note: Validation Operates On Filtered
Values Zend_Form_Element::isValid()
filters values through the provided
filter chain prior to validation. See
the Filters section for more
information.

How can I specify the order in which validators and filters run?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

小草泠泠 2024-10-21 20:02:19

当然,创建一个支持验证后过滤的自定义元素似乎是可行的方法。怎么样:

/**
 * 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 以通过按键添加/删除过滤器等。

你觉得呢?

Sure seems like creating a custom element that supports post-validation filtering would be the way to go. How about this:

/**
 * 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;
    }
}

Usage would be something like this:

$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(),
     ),
));

This keeps the validation and filtering in the form - keeping the controller thin.

Not tested, just a stab in the dark. And surely you could fatten/modify the API to add/remove filters by key, etc.

Whaddya think?

秋凉 2024-10-21 20:02:19

也许根本不添加过滤器。首先在控制器中验证内容,然后单独使用过滤器:

$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
}

我从未这样做过,但我认为这(或类似的东西)可能有效。

Maybe don't add the filter at all. Validate the content first in the controller, and then use the filter separately:

$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
}

I've never done this, but I suppose this (or something similar) might work.

逐鹿 2024-10-21 20:02:19

好点! ,

据我所知过滤器应该或必须在验证输入之前运行:
来自 ZF 文档

这通常是有用和/或必要的
对输入进行一些标准化
在验证之前。例如,你
可能想要删除所有 HTML,但是
对剩下的内容进行验证
以确保提交的内容有效。或者
你可能想修剪空白区域
周围的输入使得
StringLength 验证器将使用
正确的输入长度,无需
计算前导或尾随
空白字符。

但当且仅当你遇到无法解决的情况时,mingos 的答案必须是帮助

Good point ! ,

AFAIK filters should or must run before validating the input :
from ZF docs

It's often useful and/or necessary to
perform some normalization on input
prior to validation. For example, you
may want to strip out all HTML, but
run your validations on what remains
to ensure the submission is valid. Or
you may want to trim empty space
surrounding input so that a
StringLength validator will use the
correct length of the input without
counting leading or trailing
whitespace characters.

but if and only if you are in case which can't solve mingos's answer must be the help

二智少女 2024-10-21 20:02:19

您想要实现的是更改文本元素处理方式的默认行为。因此,我认为您可以创建自己的元素(例如 My_Form_Element_Text)来扩展 Zend_Form_Element_Text 并重载其 isValid() 方法。

具体来说,您可以将原始 isValid() 方法中的第二行从 $value = $this->getValue(); 更改为 $value = $this->getUnfilteredValue() ;。这样,您的验证将使用未过滤的值来执行。

What you want to achieve is to change default behavior of how text element is being processed. Thus, I think you could create your own element (e.g. My_Form_Element_Text) that extends Zend_Form_Element_Text and overload its isValid() method.

Specifically you could just change second line in the orginal isValid() method, from $value = $this->getValue(); into $value = $this->getUnfilteredValue();. This way your validation will be performed using unfiltered values.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文