【问题标题】:zend form email validationZend 表单电子邮件验证
【发布时间】:2011-05-27 01:33:46
【问题描述】:

我有以下代码来为用户的电子邮件地址生成一个输入字段

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

【问题讨论】:

    标签: zend-framework zend-form email-validation zend-form-element


    【解决方案1】:

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

    只需添加 true 作为 addValidator()

    的第二个参数

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

    addValidator(第 67 行)

    在链的末尾添加一个验证器

    如果 $breakChainOnFailure 为真,那么如果验证器失败,下一个 链中的验证器,如果存在,将不会被执行。

    return:提供流畅的界面

    访问:公开

    这里是签名:

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

    【讨论】:

      【解决方案2】:

      您必须创建 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"
      ));
      

      我希望这对某人有所帮助:-)

      【讨论】:

        【解决方案3】:
        $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/

        【讨论】:

        • 是的,但我也有数据库验证器,它会检查电子邮件是否已用于在网站上注册。如果我添加上述消息,即使电子邮件有效但存在于数据库中,它也会显示自定义消息。
        • 看看!!如果没有工作,那就更好了,那没关系!
        【解决方案4】:

        好像少了好几行……

        可能应该使用这个: $mailValidator = new Zend_Validate_EmailAddress();

        您还可以在此处进行一些其他验证:http://framework.zend.com/manual/en/zend.validate.set.html

        【讨论】:

          【解决方案5】:

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

          如果你想要的是:

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

          那我建议你这样做:

          $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,这样您就可以在任何表单上显示自己的消息。

          希望它可以帮助某人!

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 2013-09-08
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2014-05-28
            • 2018-08-17
            相关资源
            最近更新 更多