繁体   English   中英

构造时的学说实体验证

[英]Doctrine entity validation at construct

我正在尝试通过教义和最佳实践来提高自己。 我找到了一个很好的最佳实践演示: 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);
    }

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

Xero不需要在__constructor注入验证器服务(即糟糕的设计恕我直言)来验证您的对象。 约束在两个可能的事件上进行验证:

使用验证器服务

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

在您的控制器中,例如:

$errors = $this->get('validator')->validate($person);

if (count($errors) > 0) {
    $errorsString = (string) $errors;
}

该演示文稿采用了来自世界的最佳实践。

您要强调的原则是关于应用程序的表示层,该层可以使用可以验证用户输入表单组件,然后该数据用于实例化实体。

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

拥有一个具有有效状态的对象的含义是让一个类型为 User 的对象同时具有 name、surname 和 email 有效(例如非空)。

因此,您可以拥有以下对象:

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或者你可以看看这个关于验证的DTO对象有用捆绑。

希望这有帮助

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM