跳到內容

如何僅套用所有驗證約束的子集(驗證群組)

編輯此頁面

預設情況下,當驗證物件時,會檢查此類別的所有約束是否通過。然而,在某些情況下,您需要僅針對該類別上的部分約束來驗證物件。若要執行此操作,您可以將每個約束組織成一個或多個「驗證群組」,然後針對一個約束群組套用驗證。

例如,假設您有一個 User 類別,它在使用者註冊和使用者稍後更新其聯絡資訊時都會使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// src/Entity/User.php
namespace App\Entity;

use Symfony\Component\Security\Core\User\UserInterface;
use Symfony\Component\Validator\Constraints as Assert;

class User implements UserInterface
{
    #[Assert\Email(groups: ['registration'])]
    private string $email;

    #[Assert\NotBlank(groups: ['registration'])]
    #[Assert\Length(min: 7, groups: ['registration'])]
    private string $password;

    #[Assert\Length(min: 2)]
    private string $city;
}

透過此設定,有三個驗證群組

預設
包含目前類別和所有參照類別中不屬於其他群組的約束。在此範例中,它僅包含 city 欄位。
User
等同於 Default 群組中 User 物件的所有約束。這永遠是類別的名稱。此群組與 Default 之間的差異在如何循序套用驗證群組中說明。
registration
這是一個自訂驗證群組,因此僅包含明確與其關聯的約束。在此範例中,僅包含 emailpassword 欄位。

類別 Default 群組中的約束是未設定明確群組,或設定為等於類別名稱或字串 Default 的群組的約束。

警告

驗證 User 物件時,Default 群組和 User 群組之間沒有差異。但是,如果 User 具有嵌入式物件,則存在差異。例如,想像一下 User 具有一個 address 屬性,其中包含一些 Address 物件,並且您已將 Valid 約束新增至此屬性,以便在您驗證 User 物件時對其進行驗證。

如果您使用 Default 群組驗證 User,則 Address 類別上屬於 Default 群組的任何約束會被使用。但是,如果您使用 User 驗證群組驗證 User,則只會驗證 Address 類別上具有 User 群組的約束。

換句話說,Default 群組和類別名稱群組(例如 User)是相同的,除非該類別嵌入在另一個實際上正在驗證的物件中。

如果您有繼承(例如 User extends BaseUser)並且您使用子類別的類別名稱(即 User)進行驗證,則 UserBaseUser 中的所有約束都將被驗證。但是,如果您使用基底類別(即 BaseUser)進行驗證,則只會驗證 BaseUser 類別中的預設約束。

若要告知驗證器使用特定群組,請將一個或多個群組名稱作為第三個引數傳遞給 validate() 方法

1
$errors = $validator->validate($author, null, ['registration']);

如果未指定群組,則將套用屬於 Default 群組的所有約束。

在完整的 Symfony 專案中,您通常會透過表單程式庫間接使用驗證。有關如何在表單內使用驗證群組的資訊,請參閱如何定義要使用的驗證群組

這項工作,包括程式碼範例,根據 Creative Commons BY-SA 3.0 授權條款授權。
TOC
    版本