2016-09-22 69 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