在Zend表单元素上使用多个PregReplace过滤器

9
我希望能在单个Zend表单元素上添加多个PregReplace过滤器。 我可以使用以下代码添加一个PregReplace过滤器:
$word = new Zend_Form_Element_Text('word');
$word->addFilter('PregReplace', array(
        'match' => '/bob/', 
        'replace' => 'john'
    ));
$this->addElement($word);

我尝试过

$word = new Zend_Form_Element_Text('word');
$word->addFilter('PregReplace', array(
        'match' => '/bob/', 
        'replace' => 'john'
    ));
$word->addFilter('PregReplace', array(
        'match' => '/sam/', 
        'replace' => 'dave'
    ));
$this->addElement($word);    

但这只意味着第二个过滤器起作用了。
我如何添加多个PregReplace过滤器?

addFilter() 使用类名作为内部注册表键,因此显然您不能拥有多个相同类的过滤器。令人惊讶的是它不允许指定键的选项。也许值得作为一个问题进行提交。 - David Weinraub
4个回答

6
您所面临的问题是第二个过滤器将覆盖在Zend_Form_Element定义的过滤器堆栈($this->_filters)中的第一个过滤器。
像David在问题评论中提到的那样,过滤器堆栈使用过滤器名称作为索引($this->_filters[$name] = $filter;),这就是第二个过滤器覆盖第一个过滤器的原因。
为了解决这个问题,您可以使用自定义过滤器,如下所示:
$element->addFilter('callback', function($v) { return preg_replace(array('/bob/', '/sam/'),array('john', 'dave'), $v); });

这是通过使用内联函数(inline function)完成的,如果您没有使用 PHP 版本 5.3 或更高版本,您可以按照以下方式设置回调来使其正常工作:

$element->addFilter('callback', array('callback' => array($this, 'funcName')));

在你的表单中,在init()方法下方添加以下内容:
function funcName($v) {
    return preg_replace(array('/bob/', '/sam/'), array('john', 'dave'), $v);
}

最后,如果你只想使用PregReplace过滤器,不同于Marcin的回答(语法是错误的),你仍然可以这样做:
$element->addFilter('pregReplace', array(
          array('match' => array('/bob/', '/sam/'),
                'replace' => array('john', 'dave')
)));

那就万事大吉了 ;)

我做了这件事,但是出现了以下错误:警告:preg_replace() [function.preg-replace]:定界符不能是字母数字或反斜杠。PHP版本为PHP 5.3.1。 - afsane
我的猜测是您的模式出了问题。你能在这里发布你的代码吗?我刚刚在示例中尝试了我的代码,它完美地运行。 - Liyali
好的答案,我认为$element->addFilter('PregReplace', array(array('match' => array(), 'replace' => array())));是解决这个问题的最佳方式。 - drew010
这是我的代码:$explain = new Zend_Form_Element_Textarea('explain'); $explain -> setLabel('explain') ->addFilter('callback', array('callback' => array($this, 'mypregReplace'))) ->setValue($data['explain']) ->addDecorator('HtmlTag', array('tag' => 'div')); - afsane
这是我在那个类中的函数 public function mypregReplace($v) { return preg_replace( array("%script/uploaded%" , "http://". $_SERVER['HTTP_HOST'] . '/public/script/uploaded'), array( "[\.\./]" , ""), $v); } 它显示了这个错误 警告: preg_replace() [function.preg-replace]: 分隔符不能是字母数字或反斜杠 - afsane
我的猜测是正确的,你的模式肯定有问题。使用工具(例如这个)来编写你的模式。我不知道你究竟想做什么,但我猜这与你的主要问题无关。 - Liyali

1

由于 PregReplace 使用了 PHP 的 preg_replace 函数,我猜这样的操作可能是可行的(preg_replace 可以接受模式数组和相应替换字符串的数组):

$word = new Zend_Form_Element_Text('word');
$word->addFilter('PregReplace', array(
        'match'   => array('/bob/', '/sam/'), 
        'replace' => array('john' ,  dave)
    ));
$this->addElement($word);

虽然我还没有测试过,但希望它能够正常工作。


1
谢谢Marcin,不幸的是那个方法没有起作用。我收到了错误信息:“Zend_Filter_PregReplace没有设置有效的MatchPattern”。 - AndySidd

0

我之前无法使用'PregReplace'使示例代码正常工作。我改为使用新的Zend_Filter_PregReplace()进行调用,现在它已经可以正常工作了。

$word->addFilter(new Zend_Filter_PregReplace(array(
                'match' => array('/bob/', '/sam/'), 
                'replace'=> array('john', 'dave'))
));

我做了同样的工作,但它显示了这个错误:"警告:preg_replace() [function.preg-replace]:分隔符不能是字母数字或反斜杠"。当我单独运行每个过滤器时,它们都可以正常工作,没有错误! - afsane

-1

我正在寻找同样的响应,但没有可用的版本。

$word->addFilter(new Zend_Filter_PregReplace(new Zend_Config(array(
 'match'=>array('/bob/', '/sam/'),
 'replace'=>array('john', 'dave')
))));

请仅使用英语回答。 - Guru Kara

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接