Проверка данных
Проверка данных (валидация) отвечает на вопрос, можно ли сохранять то, что прислал посетитель. В 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() — в нём лишь поля, описанные в форме, и значения после фильтров.