Zend_Form手动设置并验证字段值


Zend_Form set and validate field value manually

我有一个带有下拉字段的Zend_Form。当用户在url中设置值时,应在此下拉列表中选择该值作为默认值。

所以我现在要做的是:

$parlang = $this->getRequest()->getParam('lang');
if($parlang){
    $this->view->filterForm->getElement('ddLanguage')->setValue($parlang);
}
if ($this->getRequest()->isPost()) {
        if($this->view->filterForm->isValid($_POST)){
...
...
...

否,我想检查变量的值是否是下拉列表的有效值?我如何在与表单验证相结合的情况下进行检查。是的,我可以对照数组检查变量,但这似乎是在"对抗框架"。

那么Zend做这种事的方法是什么呢?

编辑:对于所有感兴趣的人,我的最终解决方案是:

$parlang = $this->getRequest()->getParam('lang');
if($parlang){
    $ddLanguage = $this->view->filterForm->ddLanguage;
    if($ddLanguage->isValid($parlang)){
        $ddLanguage->setValue($parlang);
        $language = $parlang;
    }
}

我运行了一个快速测试,看起来可以使用Zend_Form_Element_Select::getMultiOption()来检查选择值中是否存在语言。

<?php
$parlang = $this->getRequest()->getParam('lang');
if ($parlang) {
    $el = $this->view->filterForm->getElement('ddLanguage');
    // attempt to get the option
    // Returns null if no such option exists, otherwise returns a
    // string with the display value for the option
    if ($el->getMultiOption($parlang) !== null) {
        $el->setValue($parlang);
    }
}

如果Multiselect元素包含一个国家列表,我只会根据URL中的值在元素值中填充一个默认值。

为了做到这一点,您可以创建一个自定义的Zend_Form_Element,如下所示:

class My_Form_Element_SelectCountry extends Zend_Form_Element_Select
{
    protected $_translatorDisabled = true;
    public function init()
    {
        $locale = Zend_Registry::get('Zend_Locale');
        if (!$locale) {
            throw new Exception('No locale set in registry');
        }
        $countries = Zend_Locale::getTranslationList('territory', $locale, 2);
        unset($countries['ZZ']);
        // fetch lang parameter and set US if there is no param
        $request = Zend_Controller_Front::getInstance()->getRequest();
        $lang = $request->getParam('lang', 'US');
        // sort your country list
        $oldLocale = setlocale(LC_COLLATE, '0');
        setlocale(LC_COLLATE, 'en_US');
        asort($countries, SORT_LOCALE_STRING);
        setlocale(LC_COLLATE, $oldLocale);
        // check weither the lang parameter is valid or not and add it to the list
        if (isset($countries[$lang])) {
            $paramLang = array($lang => $countries[$lang]);
            $countries = array_merge($paramLang, $countries);
        }        
    $this->setMultiOptions($countries);
}  

}

你从这个自定义表单中得到了这个想法。如果你想做的不是一个由国家/地区列表填充的Multiselect字段,而是一个语言列表,那么逻辑是一样的,你只需要将调用更改为静态方法Zend_Locale::getTranslationList(),并获取你需要的任何信息。

还有一件事,如果你只想在Multiselect元素中有一个元素,那么就选择Zend_Form_Element_Hidden

这有很多"如果",但我不明白从你的问题来看,你的多选元素到底是什么样子。

现在让我们看看验证方面,当您使用Multiselect元素时,Zend_Framework会自动添加一个InArray验证器,这意味着您无需检查发送的数据是否正确。isValid将为您做这件事。

如果用户让默认参数,一切都会好起来,或者他修改/删除了这个参数,默认参数(在这种情况下是en_US,请参阅上面的代码)将被设置为Multiselect字段的默认值。

为了回答您的最后一个问题,不,检查用户设置的变量并将其与数组(例如getTranslationList())进行比较并不违反框架。我想说这甚至是推荐的做事方式。