Symfony2 - 如何验证控制器中的电子邮件地址

Posted

技术标签:

【中文标题】Symfony2 - 如何验证控制器中的电子邮件地址【英文标题】:Symfony2 - How to validate an email address in a controller 【发布时间】:2013-08-21 09:20:54 【问题描述】:

symfony 中有一个电子邮件验证器,可以在表单中使用:http://symfony.com/doc/current/reference/constraints/Email.html

我的问题是:如何在我的控制器中使用此验证器来验证电子邮件地址?

这可以通过使用 php preg_match for usere 来实现,但我的问题是是否有可能使用 Symfony 已经内置的电子邮件验证器。

提前谢谢你。

【问题讨论】:

【参考方案1】:

通过使用Validator服务的validateValue方法

use Symfony\Component\Validator\Constraints\Email as EmailConstraint;
// ...

public function customAction()

    $email = 'value_to_validate';
    // ...

    $emailConstraint = new EmailConstraint();
    $emailConstraint->message = 'Your customized error message';

    $errors = $this->get('validator')->validateValue(
        $email,
        $emailConstraint 
    );

    // $errors is then empty if your email address is valid
    // it contains validation error message in case your email address is not valid
    // ...

// ...

【讨论】:

请注意,从 Symfony 2.5 开始不推荐使用 validateValue,而应该使用 validate。 Validator 服务自 2.5 版起已弃用,将在 3.0 版中删除。应该使用 Validator\RecursiveValidator 如果您想要默认但本地化的错误消息,您必须使用翻译服务:foreach($errors as $error) $message = $translator->trans($error->getMessage(),[],'validators'); 其中 $translator 的类型为 TranslatorInterface【参考方案2】:

我写了一篇关于在表单之外验证电子邮件地址(一个或多个)的帖子

http://konradpodgorski.com/blog/2013/10/29/how-to-validate-emails-outside-of-form-with-symfony-validator-component/

它还涵盖了一个常见错误,您可以在该错误中验证电子邮件约束并忘记 NotBlank

/**
 * Validates a single email address (or an array of email addresses)
 *
 * @param array|string $emails
 *
 * @return array
 */
public function validateEmails($emails)

    $errors = array();
    $emails = is_array($emails) ? $emails : array($emails);

    $validator = $this->container->get('validator');

    $constraints = array(
        new \Symfony\Component\Validator\Constraints\Email(),
        new \Symfony\Component\Validator\Constraints\NotBlank()
    );

    foreach ($emails as $email) 

        $error = $validator->validateValue($email, $constraints);

        if (count($error) > 0) 
            $errors[] = $error;
        
    

    return $errors;

希望对你有帮助

【讨论】:

Validator 服务自 2.5 版起已弃用,将在 3.0 版中删除。应该使用 Validator\RecursiveValidator【参考方案3】:

如果您在控制器本身中创建表单并希望在操作中验证电子邮件,那么代码将如下所示。

// add this above your class
use Symfony\Component\Validator\Constraints\Email;

public function saveAction(Request $request) 

    $form = $this->createFormBuilder()
        ->add('email', 'email')
        ->add('siteUrl', 'url')
        ->getForm();

    if ('POST' == $request->getMethod()) 
        $form->bindRequest($request);

        // the data is an *array* containing email and siteUrl
        $data = $form->getData();

        // do something with the data
        $email = $data['email'];

        $emailConstraint = new Email();
        $emailConstraint->message = 'Invalid email address';

        $errorList = $this->get('validator')->validateValue($email, $emailConstraint);
        if (count($errorList) == 0) 
            $data = array('success' => true);
         else 
            $data = array('success' => false, 'error' => $errorList[0]->getMessage());
        
   

   return $this->render('AcmeDemoBundle:Default:update.html.twig', array(
       'form' => $form->createView()
   ));

我也是新手,正在学习它,任何建议将不胜感激......

【讨论】:

【参考方案4】:

为什么没有人提到您可以在 FormBuilder 实例中使用“约束”键对其进行验证?首先,阅读文档Using a Form without a Class

'constraints' =>[
    new Assert\Email([
        'message'=>'This is not the corect email format'
    ]),
    new Assert\NotBlank([
        'message' => 'This field can not be blank'
    ])
],

适用于 symfony 3.1

例子:

namespace SomeBundle\Controller;

use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Validator\Constraints as Assert;

class DefaultController extends Controller


    /**
     * @Route("kontakt", name="_kontakt")
     */
    public function userKontaktAction(Request $request) // access for all
    

        $default = array('message' => 'Default input value');
        $form = $this->createFormBuilder($default)
        ->add('name', Type\TextType::class,[
            'label' => 'Nazwa firmy',
        ])
        ->add('email', Type\EmailType::class,[
            'label' => 'Email',
            'constraints' =>[
                new Assert\Email([
                    'message'=>'This is not the corect email format'
                ]),
                new Assert\NotBlank([
                    'message' => 'This field can not be blank'
                ])
            ],
        ])
        ->add('phone', Type\TextType::class,[
            'label' => 'Telefon',
        ])
        ->add('message', Type\TextareaType::class,[
            'label' => 'Wiadomość',
            'attr' => [
                'placeholder' => 'Napisz do nas ... '
            ],
        ])
        ->add('send', Type\SubmitType::class,[
            'label' => 'Wyślij',
        ])
        ->getForm();

        $form->handleRequest($request);

        if ($form->isValid()) 
            // data is an array with "name", "email", and "message" keys
            $data = $form->getData();
            // send email
            // redirect to prevent resubmision
            var_dump($data);
        
        
        return $this->render('SomeBundle:Default:userKontakt.html.twig', [
            'form' => $form->createView()
        ]);
    


结果:

请参阅有关可用验证类型的文档。 http://api.symfony.com/3.1/Symfony/Component/Validator/Constraints.html

如果您想查看除 message 之外的可用键,请转到以下文档:

http://symfony.com/doc/current/reference/constraints/Email.html

或导航到:

YourProject\vendor\symfony\symfony\src\Symfony\Component\Validator\Constraints\Email.php

从那里,您将能够看到还有什么可用的。

public $message = 'This value is not a valid email address.';

public $checkMX = false;

public $checkHost = false;

public $strict; "

另请注意,我在控制器内创建并验证了表单,这不是最佳实践,只能用于表单,您永远不会在应用程序的其他任何地方重复使用。

最佳做法是在 YourBundle/Form 下的单独目录中创建表单。将所有代码移至新的 ContactType.php 类。 (不要忘记在此处导入 FormBuilder 类,因为它不会扩展您的控制器,也无法通过 '$this' 访问此类)

[在 ContactType 类中:]

namespace AdminBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\Form\Extension\Core\Type;
use Symfony\Component\Validator\Constraints as Assert;

[在你的控制器内部:]

use YourBundle/Form/ContactType;
// use ...

//...
$presetData = []; //... preset form data here if you want to
$this->createForm('AdminBundle\Form\FormContactType', $presetData) // instead of 'createFormBuilder'
->getForm();
// render view and pass it to twig templet...
// or send the email/save data to database and redirect the form

【讨论】:

感谢检查 MX 和主机,我补充说:new Assert\Email(['checkHost' => true, 'checkMX' => true])【参考方案5】:

我对 symfony 3 的解决方案如下:

use Symfony\Component\Validator\Constraints\Email as EmailConstraint;

$email = 'someinvalidmail@invalid.asdf';
// ... in the action then call
$emailConstraint = new EmailConstraint();

$errors = $this->get('validator')->validate(
    $email,
    $emailConstraint
);

$mailInvalid = count($errors) > 0;

【讨论】:

【参考方案6】:

另一种方式 - 你可以使用egulias/EmailValidator bundle.

composer require egulias/email-validator

可以无容器使用

    use Egulias\EmailValidator\EmailValidator;
    use Egulias\EmailValidator\Validation\RFCValidation;
    
    $validator = new EmailValidator();
    $validator->isValid("example@example.com", new RFCValidation());

还捆绑可以验证 DNS 与 DNSCheckValidation

【讨论】:

以上是关于Symfony2 - 如何验证控制器中的电子邮件地址的主要内容,如果未能解决你的问题,请参考以下文章

Symfony2:使用 FOSUserBundle 时如何在控制器内获取用户对象?

Symfony2 测试中的伪造身份验证 - 控制器上的 get('security.context')->getToken() 返回的令牌与 TestCase 中设置的令牌不同

Symfony2 基于两个字段的表单验证

跨相关实体的Symfony2验证

Symfony2 实体用户提供者覆盖自定义身份验证提供者

Symfony2 中的 TPL 电子邮件模板