2016-09-22 56 views
2

我试图通过学说提高自己,并采取最佳做法。 我发现了一个很好的最佳实践:https://ocramius.github.io/doctrine-best-practices/#/50构造的学说实体验证

我尝试在__construct之后拥有一个有效的对象。 (请参阅https://ocramius.github.io/doctrine-best-practices/#/52) 但我使用@Assert注释验证我的对象。

我该如何做验证?必须在__construct对象内注入验证器服务?

我的目标:

class Person 
{ 
    /** 
    * @var int 
    * 
    * @ORM\Column(name="id", type="guid") 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="UUID") 
    * @expose 
    */ 
    private $id; 

    /** 
    * @var int 
    * 
    * @ORM\Column(name="name", type="string") 
    * @Assert\Email() 
    */ 
    private $email; 

    public function __construct($email, ValidatorInterface $validator){ 

      $this->email = $email; 
      $validator->validate($this); // good practice ? 

    } 

我的最终目标是单元测试这个实体的输入验证。

谢谢

编辑:

上Yonel的答案立足,我在构造函数的末尾添加这样的:

$errors = $validator->validate($this); 
    if(count($errors) > 0) { 
     $errorsString = (string) $errors; 
     throw new InvalidArgumentException($errorsString); 
    } 

这是一个好的做法或不?如果不是,为什么? 谢谢!

+0

检查更好的演示:命名的构造函数接受一个窗体对象这意味着形式做他的工作(与验证验证)。 – Matteo

+1

好的答案,我现在看到了,谢谢! – Xero

+0

谢谢Xero,让我知道如果你想要一个真正的答案来标记问题已解决 – Matteo

回答

1

呈现采取最好的做法无论从世界。

您正在突出显示的原则是关于应用程序的表示层,该表示层可以使用可验证用户输入的表单组件然后将此数据用于实例化实体。

在演示示例中,指定的构造函数将参数作为表单,因此电子邮件地址的验证由窗体完成(验证用户输入)。

具有带有效状态的对象的含义意欲围绕具有同时具有名称类型用户,姓广告电子邮件有效(如实施例不为空)的对象。

所以,你可以有以下对象:

class User 
{ 

    private $name; 

    private $surname; 

    private $email; 

    private function __construct(string $name, string $surname, string $email) 
    { 
     $this->name = $name; 
     $this->surname = $surname; 
     $this->email = $email; 
    } 

    public static function create(string $name, string $surname, string $email): User 
    { 
     return new static($name, $surname, $email); 
    } 

    public function fromFormData(FormInterface $form):User 
    { 
     // The form validate user input (i.e. valid email address) 
     return self::create($form->get('name'), $form->get('surname'), $form->get('email')); 
    } 

} 

另一种方法可以使用DTO或者你可以看看this有用的束约验证DTO的对象。

希望这有助于

1

Xero__constructor注入验证器服务是没有必要的(即糟糕的设计恕我直言)来验证您的对象。该约束验证两种可能的事件:

使用验证服务

提交表单数据,并检查 $form->isValid()方法 see doc
  • 直接

    要实际验证Person对象,请使用0123上的validate方法服务。验证器的工作很简单:读取类的约束(@Assert),并验证对象上的数据是否满足这些约束。如果验证失败,则返回非空列表的错误。

    在你的控制器〔实施例:

    $errors = $this->get('validator')->validate($person); 
    
    if (count($errors) > 0) { 
        $errorsString = (string) $errors; 
    } 
    
  • +0

    是的,我明白了。但是如果它在构造函数中,它会更干净,因为稍后使用它的开发人员可能会忘记执行此操作 – Xero