如何僅套用所有驗證約束的子集(驗證群組)
預設情況下,當驗證物件時,會檢查此類別的所有約束是否通過。然而,在某些情況下,您需要僅針對該類別上的部分約束來驗證物件。若要執行此操作,您可以將每個約束組織成一個或多個「驗證群組」,然後針對一個約束群組套用驗證。
例如,假設您有一個 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
- 這是一個自訂驗證群組,因此僅包含明確與其關聯的約束。在此範例中,僅包含
email
和password
欄位。
類別 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
)進行驗證,則 User
和 BaseUser
中的所有約束都將被驗證。但是,如果您使用基底類別(即 BaseUser
)進行驗證,則只會驗證 BaseUser
類別中的預設約束。
若要告知驗證器使用特定群組,請將一個或多個群組名稱作為第三個引數傳遞給 validate()
方法
1
$errors = $validator->validate($author, null, ['registration']);
如果未指定群組,則將套用屬於 Default
群組的所有約束。
在完整的 Symfony 專案中,您通常會透過表單程式庫間接使用驗證。有關如何在表單內使用驗證群組的資訊,請參閱如何定義要使用的驗證群組。