Encodera

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.

Оглавление

Проверка данных

Правила проверки в Symfony записывают атрибутами прямо над свойствами сущности. Форма применяет их сама: метод isValid() вернёт false, а рядом с полями появятся сообщения об ошибках.

Ограничения

namespace App\Entity;
 
use Symfony\Component\Validator\Constraints as Assert;
 
class Post
{
    #[ORM\Column(length: 255)]
    #[Assert\NotBlank]
    #[Assert\Length(min: 5, max: 255)]
    private ?string $title = null;
 
    #[ORM\Column(type: Types::TEXT)]
    #[Assert\NotBlank]
    private ?string $body = null;
}

Больше ничего не нужно: форма из прошлого урока начнёт отклонять пустой или слишком короткий заголовок.

Частые ограничения

ОграничениеЧто проверяет
NotBlankЗначение не пустое
Length(min: 3, max: 50)Длина строки
EmailАдрес почты
UrlАдрес сайта
Positive, PositiveOrZeroЗнак числа
Range(min: 1, max: 100)Число в границах
Choice(['draft', 'published'])Одно из значений
Regex('/^[a-z0-9-]+$/')Соответствие шаблону
Image(maxSize: '2M')Файл — картинка не больше 2 МБ

Свои сообщения

#[Assert\NotBlank(message: 'Введите заголовок')]
#[Assert\Length(
    min: 5,
    minMessage: 'Заголовок должен быть не короче {{ limit }} символов',
)]
private ?string $title = null;

Уникальность

Проверка по базе данных — ограничение над классом:

use Symfony\Bridge\Doctrine\Validator\Constraints\UniqueEntity;
 
#[ORM\Entity]
#[UniqueEntity('email', message: 'Этот адрес уже занят')]
class User
{
    #[ORM\Column(unique: true)]
    #[Assert\Email]
    private ?string $email = null;
}

Проверка вручную

Без формы объект проверяет сервис ValidatorInterface:

use Symfony\Component\Validator\Validator\ValidatorInterface;
 
public function import(ValidatorInterface $validator): Response
{
    $post = new Post();
    $post->setTitle('');
 
    $errors = $validator->validate($post);
 
    if (count($errors) > 0) {
        foreach ($errors as $error) {
            echo $error->getPropertyPath() . ': ' . $error->getMessage();
        }
    }
 
    // …
}

Правило, зависящее от нескольких полей

use Symfony\Component\Validator\Context\ExecutionContextInterface;
 
#[Assert\Callback]
public function validateDates(ExecutionContextInterface $context): void
{
    if ($this->endsAt < $this->startsAt) {
        $context->buildViolation('Окончание раньше начала')
            ->atPath('endsAt')
            ->addViolation();
    }
}

Частая ошибка

Большинство ограничений пропускают пустое значение: #[Assert\Email] считает пустую строку и null допустимыми. Если поле обязательное, добавляйте #[Assert\NotBlank] рядом. И помните: атрибут required в разметке проверяет только браузер, а его легко обойти — настоящая проверка всегда на сервере.

Спасибо, что читаете!

Пожертвуйте сайту, мы стараемся ради вас.