Encodera

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

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

Оглавление

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

Проверка данных (валидация) отвечает на вопрос, можно ли сохранять то, что прислал посетитель. В Laminas правила описывает набор InputFilter: для каждого поля задают фильтры и валидаторы. Фильтр изменяет значение — например, убирает пробелы по краям. Валидатор ничего не меняет, а решает, допустимо ли значение.

Правила в классе формы

Правила удобно держать рядом с полями. Добавьте классу PostForm интерфейс InputFilterProviderInterface и метод с правилами:

// module/Blog/src/Form/PostForm.php
use Laminas\Filter\StringTrim;
use Laminas\InputFilter\InputFilterProviderInterface;
use Laminas\Validator\StringLength;
 
class PostForm extends Form implements InputFilterProviderInterface
{
    // конструктор с полями остаётся прежним
 
    public function getInputFilterSpecification(): array
    {
        return [
            'title' => [
                'required' => true,
                'filters' => [
                    ['name' => StringTrim::class],
                ],
                'validators' => [
                    [
                        'name' => StringLength::class,
                        'options' => ['min' => 5, 'max' => 255],
                    ],
                ],
            ],
        ];
    }
}

Ключ title — имя поля. required запрещает пустое значение, filters и validators — списки, которые применяются по порядку: сначала все фильтры, затем валидаторы.

Откройте /blog/add и отправьте форму с заголовком из двух букв. Страница откроется снова, под полем появится сообщение об ошибке, а введённый текст останется на месте: действие из прошлого урока уже возвращает форму в шаблон, если isValid() вернул false.

Правила для второго поля

Добавьте в тот же массив правила для текста статьи:

'body' => [
    'required' => true,
    'filters' => [
        ['name' => StringTrim::class],
    ],
],

Теперь статью с пустым текстом сохранить нельзя.

Частые фильтры и валидаторы

Фильтр (Laminas\Filter)Что делает
StringTrimУбирает пробелы по краям
StripTagsУдаляет теги HTML
ToIntПреобразует в целое число
StringToLowerПриводит к нижнему регистру
Валидатор (Laminas\Validator)Что проверяет
StringLengthДлину строки
EmailAddressАдрес почты
DigitsТолько цифры
BetweenЧисло в границах min и max
InArrayЗначение из списка haystack
IdenticalСовпадение с другим полем (token)
RegexСоответствие шаблону pattern

Свой текст ошибки

Стандартные сообщения написаны по-английски. Текст заменяют в настройках валидатора:

[
    'name' => StringLength::class,
    'options' => [
        'min' => 5,
        'messages' => [
            StringLength::TOO_SHORT => 'Заголовок короче 5 символов.',
        ],
    ],
],

У каждого валидатора свои константы для сообщений; они перечислены в начале его класса.

Ошибки в контроллере

Все сообщения можно получить массивом — например, чтобы записать их в журнал:

if (!$form->isValid()) {
    $errors = $form->getMessages();
    // ['title' => ['stringLengthTooShort' => 'Заголовок короче 5 символов.']]
}

Проверка без формы

Для данных, пришедших не из формы HTML, достаточно одного набора правил:

use Laminas\InputFilter\Factory;
use Laminas\Validator\EmailAddress;
 
$filter = (new Factory())->createInputFilter([
    'email' => [
        'required' => true,
        'validators' => [['name' => EmailAddress::class]],
    ],
]);
 
$filter->setData(['email' => 'anna@example']);
 
if (!$filter->isValid()) {
    $errors = $filter->getMessages();
}

Адрес без домена верхнего уровня проверку не пройдёт, и в $errors окажется сообщение для поля email. Очищенные значения возвращает $filter->getValues().

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

Брать данные из $request->getPost() после проверки — ошибка: там исходные значения, без фильтров и с любыми лишними полями, которые добавил посетитель. Сохраняйте только $form->getData() — в нём лишь поля, описанные в форме, и значения после фильтров.

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

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