Як застосувати лише підмножину усіх ваших обмежень валідації (групи валідації)

Дата оновлення перекладу 2022-12-23

Як застосувати лише підмножину усіх ваших обмежень валідації (групи валідації)

За замовчуванням, при валідації обʼєкта, всі обмеження цього класу будуть перевірені на предмет того, чи дійсно вони підійдуть. Однак, у деяких випадках, вам знадобиться валідувати обʼєкт лише по відношенню до деяких обмежень цього класу. Щоб зробити це, ви можете організувати кожне обмеження в одну та більше "груп валідації", а потім застосувати валідацію лише до однієї групи обмежень.

Наприклад, уявіть, що у вас є клас User, який використовується як при реєстрації користувача, так і при оновленні контактної інформації пізніше:

  • Attributes
  • YAML
  • XML
  • PHP
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 $email;

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

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

У такій конфігурації існує три групи валідації:

Default
Містить обмеження у поточному класі і всі згадані класи, які не належать до жодної групи.
User
Еквівалентна усім обмеженням обʼєкта User в групі Default. Це завжди є іменем класу. Різниця між цією групою і Default пояснюється у Як послідовно застосовувати групи валідації.
registration
Це користувацька група валідації, тому вона містить лише обмеження, які чітко асційовані з нею. У цьому прикладі, лише поля email та password.

Обмеження у групі класу Default - це обмеження, які або не мають чітко сконфігурованої групи, або які сконфігуровані у групу, що дорівнює іменя класу або рядку Default.

Caution

При валідації лише обʼєкта Користувача, не існує різниці між групами Default і User. Але різниця існує, якщо User має вбудовані обʼєкти. Наприклад, уявіть, що User має властивість address, яка містить деякий обʼєкт Address, і що ви додали обмеження Valid до цієї властивості, щоб вона була валідована при валідації обʼєкта User.

Якщо ви валідуєте User, використовуючи групу Default, то будь-які обмеження у класі Address, які знаходяться в групі Default будуть використані. Але, якщо ви валідуєте User, використовуючи групу валідації User, тоді будуть валідовані лише обмеження класу Address.

Іншими словами, група Default і група класу імені (наприклад, User) ідентичні, окрім випадків, коли клас вбудований в інший обʼєкт, ніж той, валідація якого проводиться.

Якщо у вас є наслідування (наприклад, User extends BaseUser) і ви валідуєте з класом імені підкласу (тобто, User), то всі обмеження в User і BaseUser будуть валідовані. Однак, якщо ви валідуєте, використовуючи базовий класс (тобто, BaseUser), то будуть валідовані лише обмеження за замовчуванням у класі BaseUser.

Щоб повідомити валідатору про використання конкретної групи, передайте одне або більше імен груп в якості третього аргументу методу validate():

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

Якщо не вказана жодна група, будуть застосовані всі обмеження, які належать до групи Default

Авжеж, ви частіше працюватимете з валідацією не напряму, а через бібліотеку форм. Для інформації про те, як використовувати групи валідації всередині форм, дивіться Як визначити, які групи валідації використовувати.