Zend表单电子邮件验证

8
我有以下代码来生成一个用户邮箱地址的输入框。
$email = new Zend_Form_Element_Text('email');
$email->setLabel('Email:')
    ->addFilters(array('StringTrim', 'StripTags'))
    ->addValidator('EmailAddress')
    ->addValidator(new Zend_Validate_Db_NoRecordExists(
                                                        array(
                                                                'adapter'=>Zend_Registry::get('user_db'),
                                                                'field'=>'email',
                                                                'table'=>'tbl_user'
                                                                )))
    ->setRequired(true)
    ->setDecorators(array(
                            array('Label', array('escape'=>false, 'placement'=>'append')),
                            array('ViewHelper'),
                            array('Errors'),
                            array('Description',array('escape'=>false,'tag'=>'div')),
                            array('HtmlTag', array('tag' => 'div')),
                        ));
$this->addElement($email);

现在的问题是,如果用户输入无效的邮件主机名,它会生成3个错误。比如说,如果用户输入'admin@l'作为电子邮件地址,那么错误将会是:
* 'l'不是电子邮件地址'admin@l'的有效主机名
* 'l'与DNS主机名的预期结构不匹配
* 'l'似乎是一个本地网络名称,但本地网络名称是不允许的。
我只想让它给出一个自定义错误,而不是所有这些错误。如果我通过addErrorMessage方法设置错误消息“无效的电子邮件地址”,它将再次针对db_validation生成相同的消息。
5个回答

8

好的,虽然回答晚了,但我认为它仍然有用。

只需将addValidator()的第二个参数设置为true

来自Zend文档(http://framework.zend.com/apidoc/1.8/):

addValidator (第67行)

将验证器添加到链的末尾

如果$breakChainOnFailure为true,则如果验证器失败,则不会执行链中的下一个验证器(如果存在)。

返回:提供流畅的接口

访问:public

这里是签名:

Zend_Validate addValidator (Zend_Validate_Interface $validator, [boolean $breakChainOnFailure = false])

Zend_Validate_Interface $validator
boolean $breakChainOnFailure

所以代码如下:
$email = new Zend_Form_Element_Text('email');
$email->setLabel('Email:')
    ->addFilters(array('StringTrim', 'StripTags'))
    ->addValidator('EmailAddress',  TRUE  ) // added true here
    ->addValidator(new Zend_Validate_Db_NoRecordExists(
                array(
                        'adapter'=>Zend_Registry::get('user_db'),
                        'field'=>'email',
                        'table'=>'tbl_user'
                        ), TRUE )
            );

5

您需要创建Zend_Validate_EmailAddress类的实例,并调用setMessages方法,然后覆盖您喜欢的消息,以删除您提到的那些消息,代码示例如下:

$emailValidator->setMessages(array(
    Zend_Validate_EmailAddress::INVALID_FORMAT => "Your error message",
    Zend_Validate_Hostname::INVALID_HOSTNAME => "Your error message",
    Zend_Validate_Hostname::LOCAL_NAME_NOT_ALLOWED => "Your error message"
));

我希望这可以帮助某些人 :-)


2
$email->addErrorMessage("Please Enter Valid Email Address");

您可以使用自定义验证器。在项目根目录下的 library 文件夹中的 Validate 文件夹内创建一个名为 Email.php 的文件。

class Validate_Email extends Zend_Validate_Abstract
{

    const INVALID = 'Email is required';
    protected $_messageTemplates = array(
    self::INVALID => "Invalid Email Address",
    self::ALREADYUSED => "Email is already registered"
    );

     public function isValid($value)
     {
          if(preg_match($email_regex, trim($value))){
            $dataModel = new Application_Model_Data(); //check if the email exists
            if(!$dataModel->email_exists($value)){
                return true;
            }
            else{
                $this->_error(self::ALREADYUSED);
                return false;
            }
          }
          else
          {
            $this->_error(self::INVALID);
            return false;
          }
     }
}

在您的 form.php 文件中

    $mailValidator = new Validate_Email();
    $email->addValidator($mailValidator, true);

不知道它是否有效,但对于我来说,在电话的情况下它有效。感谢http://softwareobjects.net/technology/other/zend-framework-1-10-7-telephone-validator/


是的,但我还有一个数据库验证器,它会检查电子邮件是否已用于注册该网站。如果我添加上述消息,即使电子邮件有效但存在于数据库中,它也将显示自定义消息。 - Bryan
看看吧!如果有效就更好,如果无效也没关系! - S L

0

使用自定义验证器是我发现避免这个问题的唯一方法。

如果你想要的是:

  • 只有一个错误消息,如果电子邮件地址格式不正确
  • 如果格式正确,则验证电子邮件地址是否已经在数据库中

那么我建议你做类似于这样的事情:

$where = array('users', 'email', array('field' => 'user_id',
                                       'value' => $this->getAttrib('user_id')));
$email = new Zend_Form_Element_Text('email');
$email->setLabel('E-mail:')
      ->setRequired(true)
      ->setAttrib('required name', 'email') // html5
      ->setAttrib('maxlength', '50')
      ->addFilter('StripTags')
      ->addFilter('StringTrim')
      ->addFilter('StringToLower')
      ->addValidator('email', true)
      ->addValidator('stringLength', true, array(1, 50))
      ->addValidator('db_NoRecordExists', true, $where)
      ->addDecorators($this->_elementDecorators);
$this->addElement($email);

$this->getAttrib('user_id') 表示 当前用户的 ID

这里有三个验证器,它们的第二个参数 $breakOnFailure 都设置为 false,所以如果一个验证器失败了,其他的验证器就不会被调用。

第一个验证器是 email,这是我自己定义的验证器:

class My_Validate_Email extends Zend_Validate_EmailAddress
{
    public function getMessages()
    {
        return array('invalidEmail' => 'Your email address is not valid.');
    }
}

您可以将此验证器添加到您的库中,例如在/application/library/My/Validate中,然后将 $this->addElementPrefixPath('My_Validate', 'My/Validate', 'validator'); 添加到您的表单中。当然,您需要将"My"替换为您的库名称。

现在,如果电子邮件格式不正确,将始终显示“您的电子邮件地址无效”。如果您的电子邮件太长并且不适合您的数据库字段(例如VARCHAR(100)),它将显示您的stringLength验证器错误,而在最后一种情况下,如果数据库中已经存在一个条目,则只会显示此错误。

当然,您可以向自定义验证器中添加更多方法,并重载setMessages,以便在处理任何表单时都可以显示您自己的消息。

希望它能帮助某些人!


0

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