【问题标题】:Symfony2 - Call EmailValidator inside a Custom ValidatorSymfony2 - 在自定义验证器中调用 EmailValidator
【发布时间】:2013-06-27 07:41:56
【问题描述】:

我正在创建一个自定义验证器约束来验证“联系人”,类似于“John Doe ”。在Cookbook 之后,我创建了约束类:

<?php

namespace MyCompany\MyBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;

/**
 * @Annotation
 */
class Contact extends Constraint
{
    public $message = 'The string "%string%" is not a valid Contact.';
}

并且还创建了验证器:

<?php

namespace MyCompany\MyBundle\Validator\Constraints;

use Symfony\Component\Validator\Constraint;
use Symfony\Component\Validator\ConstraintValidator;
use Symfony\Component\Validator\Constraints\Email;
use Symfony\Component\Validator\Constraints\EmailValidator;

class ContactValidator extends ConstraintValidator
{
    public function validate($value, Constraint $constraint)
    {
        if (!preg_match('#(.*)\s+<(.*)>#', $value, $matches)) {
            $this->context->addViolation($constraint->message, array('%string%' => $value));
        }

        $emailValidator = new EmailValidator();
        if (isset($matches[2]) && $emailValidator->validate($matches[2], new Email())) {
            $this->context->addViolation($constraint->message, array('%string%' => $value));    
        }
    }
}

关键是我试图在我的自定义验证器中使用 Symfony 的 EmailValidator 来检查电子邮件是否有效。我不想重新发明轮子并使用我自己的正则表达式验证电子邮件。

在尝试验证有效联系人时一切正常,但是使用无效电子邮件(“Gabriel Garcia ”)测试联系人时会出现 PHP 致命错误:

致命错误:在第 58 行的 /home/dev/myproject/vendor/symfony/symfony/src/Symfony/Component/Validator/Constraints/EmailValidator.php 中的非对象上调用成员函数 addViolation()

深入研究 EmailValidator.php 类,我意识到问题与 $context (ExecutionContext) 有关。这是 EmailValidator.php 的第 58 行:

$this->context->addViolation($constraint->message, array('{{ value }}' => $value));

似乎该类的上下文属性为空。有谁知道为什么?我需要在某处注射吗?

提前致谢。

P.S.:我使用的是 Symfony 2.3。不要关注正则表达式,我知道它可以更好。现在只是为了测试。

【问题讨论】:

    标签: php symfony symfony-2.3


    【解决方案1】:

    我认为最初的问题是关于在自定义验证器中使用 EmailValidator 并且在这种情况下容器不可用,所以

    $this->get('validator');
    

    不会工作。似乎发布者唯一的问题是将 EmailValidator addViolation 添加到正确的上下文中。这应该有效:

    $emailValidator = new EmailValidator();
    $emailValidator->initialize($this->context);
    $emailValidator->validate($matches[2], $constraint);
    

    【讨论】:

      【解决方案2】:

      可以直接使用约束

      http://symfony.com/doc/current/book/validation.html

      use Symfony\Component\Validator\Constraints\Email
      
      $emailConstraint = new Email();
      
      // use the validator to validate the value
      $errorList = $this->get('validator')->validateValue(
          $email,
          $emailConstraint
      );
      

      最好的尊重

      【讨论】:

      • 如果我将验证器定义为服务,如何注入 EmailValidator?我已经完成了一个应用程序/控制台容器:调试,但我看不到与之对应的服务...
      • 我编辑我的帖子。您不需要服务,只需要电子邮件约束对象来验证您的电子邮件。
      • 谢谢!最后,我将验证器服务注入到我的自定义验证器中,并使用它来验证“联系人”的电子邮件部分。
      • 但是如果我无法访问验证器服务如何使用它?
      【解决方案3】:

      在尝试在 custom 中调用 custom 后发现这个话题,我做了深入的研究,我可能只是找到了另一种更好的方法(根据我来说更简单)。

      有效:Sf2.6>=

      $this->context->getValidator()
          ->inContext($this->context)
          ->atPath("time_on_point")
          ->validate($timeOnPoint, new AssertCustom\DateTimeRange(array('min' => '+1 day')));
      

      在这种情况下,我声明了一个新的自定义验证器,例如 class specific Validator,我可以直接按其名称访问该字段。 这样做的好处:我可以通过只应用“new AssertCustom”来调用另一个自定义,如果这个“AssertCustom”需要一个像构造这样的服务,我将没有依赖,因为配置服务会透明地调用所有的东西。

      小心,如果你调用递归(深度)字段,你需要根据在这个文件中找到的 cmets 来调整上下文:Symfony\Component\Validator\Constraints\CollectionValidator

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2015-03-11
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-07-14
        相关资源
        最近更新 更多