Pull to refresh

Comments 31

И опять нет ответа на вопроса — какие существенные отличия вашего велосипеда от представленных ранее?

@franzose Посмотрел вашу библиотеку, есть несколько моментов:


  • вы не проверяете вводимые настройки для валидации так же не проверяете, а доступен ли валидатор для конкретно этого типа. Пример для Length.php
  • ваш валидатор подходит только для проверки пользовательского ввода. Это не то, что бы недостаток, а скорее ограничение применения. В случае, если проверять придется много — ваш валидатор станет довольно прожорливой штукой так как на каждую проверку создается тьма объектов.
  • По своему опыту скажу: задание правил проверки в стиле "not_empty|length:5,15" для крупных проектов — скорее минус, чем плюс. Так как корректность этих правил вы можете узнать на момент запуска, а не на момент написания.

Посмотрите на досуге: ko-ko-ko/assert

правила в стиле not_empty|length:5,15

Дополню список проблем:
  1. Если передать в качестве аргумента строку с запятой, все сломается (говорю исходя из кода).
  2. Нет возможности передать массив, да даже если его и передавать, например как JSON, будут опять же проблемы из п.1 с запятыми


Т.е. в библиотеке такое определение работает «иногда».
Сделайте правильный выбор

Выбираю Zend\Validator :)
Ну, так как пишу на Laravel чаще всего, то тоже выбрал бы стандартный валидатор. Но если бы пришлось писать на чем-то другом или собирать проект из отдельных пакетов, то тут бы я подумал)
имхо, для проекта надо добавить свой интерфейс Validator (плюс ValidatorResponse). Для каждого кейса валидации следует реализовать конкретный валидатор — UserValidator, CreatePostValidator итд, а вот внутри будет реализация на любой библиотеке из представленных в посте и не представленных.
Итого гибкость, заменяемость, контрактное программирование итд.

UPD: причем в таких «узких» валидаторах необязательно пользоваться либами. Можно простые проверки делать базовыми функциями типа is_int, а сложные (проверка емейла с тысячью доменов первого уровня) — с использованием специализированных валидаторов.
Так и делаем, для этого в Zend есть «формы» как агрегаторы валидаторов и фильтров.
Спасибо большое, очень интересный обзор библиотек.

Немного усложню кейс.
Допустим поле email необязательное.
А вот если ставим галочку «подписаться на новости» — то теперь поле email становится обязательным.
Какая из библиотек умеет работать с такой логикой?

В Yii это делается через сценарии. Т.е. вначале валидации надо указать сценарий (с подпиской, или без подписки), а в самих правилах указать как действовать в том или ином сценарии.

Не уверен, что это лучшее решение, но можно сделать форму где email не обязательное и вторую форму которая наследует первую и только переписывает правило для email. и когда человек сабмитит форму — в зависимости от логики — ты можешь создать нужную тебе форму и провалидировать ее.
Можно же добавить свое правило валидации для поля email и в нем проверять стоит ли галочка.
Это если у тебя есть доступ к заполняемой форме внутри кастом правила :) Иногда правило — достаточно «изолирован» и не знает ничего кроме самого себя…

Можно переопределить конструктор и передать значение в него. Немного костыльно, но как вариант.

Тут надо смотреть как инициализируются правила. Если ты сам их инициализируешь и пихаешь в валидатор — то да, а если допустим ты просто передаешь кастомные рулсы в каком конфиге и они уже разворачиваются внутри валидатора — то тут уже не сработает.
Переносить логику формы в правила валидации?

А если так:
1) Физическое или Юридическое
2) Если юридическое — то нужны новые обязательные поля (ИНН, Юр адрес, и ещё 100500 полей)
И получается чо надо создать множество правил, в которых надо проверить галочку. Которую, кстати, тоже надо проверить.

Так форма ничего и не должна знать о логике. Логикой пусть занимается модель, а задача валидаторов не пустить в неё некорректные наборы данных из формы.

Присоединяюсь к sefus. Любой из представленных валидаторов поддерживает кастомные правила, так что можно реализовать через них. А вот на вопрос, есть ли в них готовые правила по типу required_with точно сейчас не смогу ответить. По крайней мере в Kontrolio такого правила нет.

Чуть ниже уже писали, что это уже бизнес-логика и такое должна валидировать модель. Форма должна валидировать только формат, а модель — сущности. То есть в вашем случае валидатор формы должен проверить: поле email либо пустое, либо проходит через валидацию формата email. А модель проверяет, что поле email заполнено при проставленном флаге.

Не все так просто. Галочка «подписаться на новости» — это такой элемент интерфейса, а на самом деле означает действие «подписка на новости», в коде получится что-то вроде:

$user = new User(...);
if ($request->get('subscribe_to_news')) {
$subscriber->subscribeToNews($user); // может бросить исключение UserEmailRequired
}

И тут уж проще добавить правило в валидацию формы, чем ловить исключение и вручную формировать ответ.
Laravel валидатор имеет широкий функционал для такого типа проверок:
required_if:anotherfield,value,…
required_unless:anotherfield,value,…
required_with:foo,bar,…
required_with_all:foo,bar,…
required_without:foo,bar,…
required_without_all:foo,bar,…
Учитывая, что 90% моих проектов на Zend/Symfony, использую Zend\Validator, Symfony\Validator соответственно, особенно нравится Symfony вариант. Больше всего в их решениях привлекает тот факт, что валидация выглядит не отдельной библиотекой которую ты используешь, а интегрированным модулем который ты можешь использовать где угодно (валидация Entity, валидация форм и так далее).

Такие standalone-библиотеки, как мне кажется, в основном рассчитаны на тех, кто собирает какие-то свои решения из набора компонентов, а не использует готовые фреймворки. И оба подхода имеют право на существование)

Полностью согласен, но опять же Symfony отлично славится своими компонентами :) Берешь Symfony Forms и используешь. Но естественно, должна быть граница и здравый смысл в выборе между использованием легкой библиотеки валидации и огромного компонента для форм от симфонии…
UFO just landed and posted this here
А еще не забываем о PHPixie Validate, который в отличии от других библиотек работающих только с одномерными массивами умеет валидировать вложенные структуры типа:

$data = array(
    'name' => 'Pixie',
    'home' => array(
        'location' => 'forest',
        'name'     => 'Oak'
    ),
    'spells' => array(
        'charm' => array(
            'name' => 'Charm Person',
            'type' => 'illusion'
        ),
        'blast' => array(
            'name' => 'Fire Blast',
            'type' => 'evocation'
        ),
        // ....
    )
);


Что фактически необходимо при работе со всякими ангулярами и MongoDB

Если не ошибаюсь, все рассмотренные библиотеки это также умеют. Наверно, надо было включить такой пример в статью.

«Ваши имя и фамилия должны состоять ровно из двух слов» — по слогам прочитал Гасан Абдурахман ибн Хоттаб, после чего вздохнул, пожал плечами, завернул золотишко в платок и отправился на сайт конкурентов.

Согласен. Но суть была показать, как в тех или иных библиотеках обрабатываются не совсем стандартные случаи)

Нужно мне было валидировать XHR-запрос, прилетающий в бэкэнд от JS-плагина DataTables. Сам запрос достаточно «развесистый» в структурном плане. Описание тут — https://www.datatables.net/manual/server-side. Обычно использую Symfony Validator, и в этом случае поступил аналогично — https://github.com/arodygin/DataTablesBundle/blob/master/src/Parameters.php.

Вопрос: Kontrolio так умеет? В частности:
  • проверку «вложенных» структур и массивов,
  • запрет/разрешение лишних атрибутов,
  • запрет/разрешение отсутствия атрибута.

Ни в коем случае не нападаю, просто интересуюсь, а тратить время на эксперименты с вашей библиотекой не хочется. Если есть — отлично. Если нет — имейте в виду. ;)

Вложенные массивы Kontrolio валидировать умеет. Возможно, не так красиво по сравнению с другими решениями. Можно записать так:


$rules = ['attr.nested.nested.nested' => 'not_empty'];
$messages = ['attr.nested.nested.nested' => 'Не может быть пустым.'];

Отсутствие атрибута можно разрешить правилом Sometimes:


$rules = ['attr.nested.nested.nested' => [new Sometimes, new Length(5, 15)];

А вот «лишние» атрибуты не умеет отфильтровывать. Грубо говоря, что в библиотеку передали, то она и будет валидировать :)

Sign up to leave a comment.

Articles