Callback

Дата оновлення перекладу 2024-06-29

Callback

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

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

Note

Метод зворотного виклику сам по собі не може бути неуспішним або повернути якесь значення. Замість цього, як ви побачите у прикладі, метод зворотного виклику має здібність напрряму додати "порушення" валідатора.

?????????????? ?? ????? ??? ???????????/??????
???? Callback
????????? CallbackValidator

Конфігурація

1
2
3
4
5
6
7
8
9
10
11
12
13
14
// src/Entity/Author.php
namespace App\Entity;

use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;

class Author
{
    #[Assert\Callback]
    public function validate(ExecutionContextInterface $context, mixed $payload): void
    {
        // ...
    }
}

Метод зворотного виклику

Методу зворотного виклику передається спеціальний обʼєкт ExecutionContextInterface. Ви можете встановити "порушення" прямо в цьому обʼєкті та визначити, до якого поля мають бути приписані ці помилки:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// ...
use Symfony\Component\Validator\Context\ExecutionContextInterface;

class Author
{
    // ...
    private string $firstName;

    public function validate(ExecutionContextInterface $context, mixed $payload): void
    {
        // якимось чином у вас є масив "фальшивих імен"
        $fakeNames = [/* ... */];

        // перевірити, чи є імʼя дійсно фальшивим
        if (in_array($this->getFirstName(), $fakeNames)) {
            $context->buildViolation('This name sounds totally fake!')
                ->atPath('firstName')
                ->addViolation();
        }
    }
}

Статичні зворотні виклики

Ви також можете використати обмеження зі статичними методами. Так як статичні методи не мають доступу до екземпляру обʼєкта, вони отримують обʼєкт в якості першого аргументу:

1
2
3
4
5
6
7
8
9
10
11
12
13
public static function validate(mixed $value, ExecutionContextInterface $context, mixed $payload): void
{
    // якимось чином у вас є масив "фальшивих імен"
    $fakeNames = [/* ... */];

    // перевірити, чи є імʼя дійсно фальшивим
    if (in_array($value->getFirstName(), $fakeNames)) {
        $context->buildViolation('This name sounds totally fake!')
            ->atPath('firstName')
            ->addViolation()
        ;
    }
}

Зовнішні зворотні виклики та замикання

Якщо ви хочете виконати статичний метод зворотного виклику, який не знаходиться у класі обʼєкта, що валідується, ви можете сконфігурувати обмеження так, щоб воно запускали викликане масиву, як це підтримумється PHP-функцією call_user_func. Уявіть, щов ваша функція валідації - Acme\Validator::validate():

1
2
3
4
5
6
7
8
9
10
11
namespace Acme;

use Symfony\Component\Validator\Context\ExecutionContextInterface;

class Validator
{
    public static function validate(mixed $value, ExecutionContextInterface $context, mixed $payload): void
    {
        // ...
    }
}

Потім ви можете використати наступну конфігурацію для виклику цього валідатора:

1
2
3
4
5
6
7
8
9
10
// src/Entity/Author.php
namespace App\Entity;

use Acme\Validator;
use Symfony\Component\Validator\Constraints as Assert;

#[Assert\Callback([Validator::class, 'validate'])]
class Author
{
}

Note

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

При конфігурації обмеження через PHP, ви також можетеп передати замикання у конструктор обмеження зворотного виклику:

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

use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\Validator\Context\ExecutionContextInterface;
use Symfony\Component\Validator\Mapping\ClassMetadata;

class Author
{
    public static function loadValidatorMetadata(ClassMetadata $metadata): void
    {
        $callback = function (mixed $value, ExecutionContextInterface $context, mixed $payload): void {
            // ...
        };

        $metadata->addConstraint(new Assert\Callback($callback));
    }
}

Caution

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

Опції

callback

тип: string, array або Closure [опція за замовчуванням ]

Опція зворотного виклику приймає три різних формати для вказання методу зворотного виклику:

  • Рядок, що містить імʼя конкретного або статичного методу;
  • Викличне масиву у форматі array('<Class>', '<method>');
  • Замикання.

Конкретні зворотні виклики отримують екземпляр ExecutionContextInterface в якості єдиного аргументу.

Статичні або замикаючі зворотні виклики отримують валідований обʼєкт в якості першого аргументу, а екземпляр ExecutionContextInterface - в якості другого.

Дата оновлення перекладу 2023-09-24

groups

тип: array | string за замовчуванням: null

Визначає групу або групи валідації обмеження. Прочитайте більше про групи валідації.

Дата оновлення перекладу 2024-05-29

payload

тип: mixed за замовчуванням: null

Ця опція може бути використана, щоб додати довільні дані, специфічні для домену, до обмеження. Сконфігуроване корисне навантаження не використовується компонентом Validator, але його обробка повністю залежить від вас.

Наприклад, ви можете захотіти використати декілька рівнів помилок, щоб представити неуспішні обмеження по-різному у фронтенді, залежно від серйозності помилки.