Zend的形式验证电子邮件

问题描述:

我有下面的代码来生成输入域用户的电子邮件地址Zend的形式验证电子邮件

$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生成相同的消息。

嗯,这是一个迟到的答案,但我想,总是有用的。

只需添加在addValidator()

从Zend的文档(http://framework.zend.com/apidoc/1.8/)的第二PARAM:

addValidator(线67)

添加一个验证程序的末端的链

如果$ breakChainOnFailure为true,那么如果验证程序失败,链中的下一个 验证程序(如果存在)将不会执行。

回报:提供流畅的界面

访问:公共

这里的招牌:

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) 
      ); 

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

您可以使用自定义的验证。在项目

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

的根源,并在您的库中创建一个文件Email.php文件夹验证文件夹你form.php的文件

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

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

+0

是的,但我也有DB验证器,它检查电子邮件是否已用于注册该网站。如果我添加上面的消息,即使在电子邮件有效但存在于数据库中的情况下,它也会显示自定义消息。 – Bryan 2010-12-21 08:34:08

+0

看看吧!如果没有工作,那么工作就更好了,那就没问题了! – 2010-12-21 09:00:41

+0

我会在周末进行测试,并会让你知道。谢谢 – Bryan 2010-12-23 11:50:58

它似乎缺少了不少行礼貌......

也许应该这样做: $ mailValidator =新Zend_Validate_EmailAddress();

你也可以做一些其他的验证在这里看到:http://framework.zend.com/manual/en/zend.validate.set.html

你必须创建Zend_Validate_EmailAddr的一个实例ESS类并调用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" 
)); 

我希望这个帮助别人:-)

+0

谢谢,这很有帮助! – 2011-07-31 06:17:23

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

如果你想要的是:

  • 只有一个错误消息,如果电子邮件地址是在一个错误的格式
  • 如果格式是好的,那么验证如果电子邮件地址已在数据库

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

$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')代表当前用户的标识

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

第一确认是电子邮件,这是我自己的自定义验证:

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

您可以在库中添加这个验证,在/应用程序/库/我的/验证例如,然后添加 $this->addElementPrefixPath('My_Validate', 'My/Validate', 'validator'); 进入您的表单。当然,您需要用您的图书馆名称替换“我的”。

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

当然,您可以将更多方法添加到自定义验证程序和重载setMessages中,以便您可以显示自己的消息,无论您正在使用哪种形式。

希望它可以帮助别人!