Фильтры в rules() модели

Общие вопросы по использованию второй версии фреймворка. Если не знаете как что-то сделать и это про Yii 2, вам сюда.
Аватара пользователя
Faenir
Сообщения: 292
Зарегистрирован: 2010.01.06, 01:46
Откуда: Симферополь

Фильтры в rules() модели

Сообщение Faenir »

Я верно понял, что валидаторы исполняются тупо по очереди и если вставить фильтр после валидаторов, то он не будет принимать участия в предыдущих валидаторах?

Пример, который протестил только что.
Создаю запись 'slug' = 'test', затем создаю запись 'slug' = ' test ' (с пробелами, для теста trim).
Два варианта rules():

Код: Выделить всё

    // вариант 1
    return [
        ['slug', 'trim'],
        ['slug', 'unique']
    ];

    // вариант 2
    return [
        ['slug', 'unique'],
        ['slug', 'trim']      
    ];
Вариант 1 - все ок, ошибка в форме.
Вариант 2 - форма проходит валидацию, после получаю ошибку бд (SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'test' for key 'slug'). Не было бы уникального ключа в бд - спокойно записались бы дубликаты, т.к. trim все же применяется, но уже после валидации.

Собственно к чему я это... довольно не очевидный момент, с возможно печальными последствиями. В доках нигде не нашел инфу про это. Часто встречаю на гитхабе именно второй вариант использования. Да что далеко ходить... вот dektrium/yii2-user знаменитый: https://github.com/dektrium/yii2-user/b ... r.php#L235
rak
Сообщения: 2181
Зарегистрирован: 2010.11.02, 23:40
Контактная информация:

Re: Фильтры в rules() модели

Сообщение rak »

https://github.com/yiisoft/yii2/blob/ma ... idation.md
3. Каждое активное правило проверяет каждый активный атрибут, который ассоциируется с правилом. Правила проверки выполняются в том порядке, как они перечислены.
Nerf
Сообщения: 780
Зарегистрирован: 2015.01.29, 00:37

Re: Фильтры в rules() модели

Сообщение Nerf »

Собственно к чему я это... довольно не очевидный момент, с возможно печальными последствиями.
Очевидный. Какая у вас альтернатива: с конца, случайно? Были разговоры, что лучше вообще разделить правила валидации и фильтрацию.
Аватара пользователя
Faenir
Сообщения: 292
Зарегистрирован: 2010.01.06, 01:46
Откуда: Симферополь

Re: Фильтры в rules() модели

Сообщение Faenir »

Не очевидный, т.к. многие добавляют фильтры после валидации, пример я уже привел. Можно еще кучу таких примеров найти на гитхабе. Разделить было бы отлично. Либо на уровне фреймворка применять сначала фильтры, а потом уже валидацию. Не могу придумать, в каком случае фильтрация может понадобиться после валидации.

Примеры:

https://github.com/amnah/yii2-user/blob ... er.php#L98
https://github.com/modernkernel/yii2-sk ... rm.php#L42
https://github.com/cloud-github/yii2-cm ... er.php#L80

Очевидно, говорите?
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Фильтры в rules() модели

Сообщение ElisDN »

Faenir писал(а):Очевидно, говорите?
Вам неочевиден foreach в PHP?
Faenir писал(а):Разделить было бы отлично.
Можете потроллить в viewtopic.php?f=27&t=31259
Аватара пользователя
Faenir
Сообщения: 292
Зарегистрирован: 2010.01.06, 01:46
Откуда: Симферополь

Re: Фильтры в rules() модели

Сообщение Faenir »

ElisDN писал(а): 2017.01.17, 11:26Вам неочевиден foreach в PHP?
Я привел примеры кода других разработчиков. Если они фильтруют данные после проверки на уникальность, то что остановит новичков, например?
Тот топик читал, и полностью согласен с мнением zelenin.
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Фильтры в rules() модели

Сообщение ElisDN »

Faenir писал(а):то что остановит новичков, например?
Удалят разок не ту папку - научатся делать бекапы.
Затрут чужие файлы на продакшене по FTP - научатся пользоваться гитом.
Влетят на утечку паролей по FTP - перейдут на SFTP.
Найдут на загруженный shell - научатся выставлять права на папки.
Узнают про утечку исходников из .git - научатся закрывать в .htaccess.
Заплатят за неправильный расчёт цены - научатся писать тесты.
Влетят на неустойку за простой сервера - научатся CI.
Влетят на брутфорс паролей - перестанут использовать MD5.
Дропнется таблица в базе - вычистят SQL Injection.
Получат кучу фидбека про спам - включат HTMLPurifier.
Упрутся в тонны кода и сценариев в ActiveRecord - научатся рефакторить.
...

На то они и новички.
Аватара пользователя
Faenir
Сообщения: 292
Зарегистрирован: 2010.01.06, 01:46
Откуда: Симферополь

Re: Фильтры в rules() модели

Сообщение Faenir »

По такой логике вообще без фреймворка надо писать, много чему научишься. А раз уже пишешь на фреймворке, то он должен помогать разработчику, а не наоборот. И опять же, я не думаю, что автор "dektrium/yii2-user" - новичок.
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Фильтры в rules() модели

Сообщение ElisDN »

Faenir писал(а):По такой логике вообще без фреймворка надо писать, много чему научишься.
По любой логике нужно сначала изучать PHP и сопутствующие основы, а потом уже переходить на любительские и профессиональные фреймворки. А не наоборот, как это любят с Yii.
Faenir писал(а):А раз уже пишешь на фреймворке, то он должен помогать разработчику, а не наоборот.
Вменяемый разработчик с фреймворком напишет больше хорошего кода. Логично.
Невменяемый разработчик с фреймворком напишет больше плохого кода. Логично.
Faenir писал(а):И опять же, я не думаю, что автор "dektrium/yii2-user" - новичок.
Репозиторию уже три года. Судя по использованию $mailer, $this->module, Yii::$app->authManager, Yii::$app->user->login(), Yii::$app->session->setFlash(), Yii::$app->request->getUserIp() и отправки письма перед $transaction->commit() внутри одной несчастной models\User у автора тогда были не лучшие времена.
Matvik
Сообщения: 194
Зарегистрирован: 2013.06.21, 02:32

Re: Фильтры в rules() модели

Сообщение Matvik »

Код: Выделить всё

ii::$app->user->login(), Yii::$app->session->setFlash()
А собственно, так плохо?
rak
Сообщения: 2181
Зарегистрирован: 2010.11.02, 23:40
Контактная информация:

Re: Фильтры в rules() модели

Сообщение rak »

Matvik писал(а): 2017.01.17, 23:33

Код: Выделить всё

ii::$app->user->login(), Yii::$app->session->setFlash()
А собственно, так плохо?
имеется в виду, что это всё происходит в модели
Nerf
Сообщения: 780
Зарегистрирован: 2015.01.29, 00:37

Re: Фильтры в rules() модели

Сообщение Nerf »

Faenir писал(а): 2017.01.17, 09:25 Не очевидный, т.к. многие добавляют фильтры после валидации, пример я уже привел. Можно еще кучу таких примеров найти на гитхабе. Разделить было бы отлично. Либо на уровне фреймворка применять сначала фильтры, а потом уже валидацию. Не могу придумать, в каком случае фильтрация может понадобиться после валидации.
Я тоже добавляю фильтры после валидации, а иногда до. И это работает (иногда нет :lol: ). Ваша проблема в том, что вы не можете "придумать, в каком случае фильтрация может понадобиться после валидации". То, что кто-то не может расставить правила в нужной последовательности - не аргумент. Тут некоторые пытаются писать запросы через построитель, не умея писать голый sql...
Почему вы не жалуетесь на UrlManager::$rules и прочее?
Аватара пользователя
Faenir
Сообщения: 292
Зарегистрирован: 2010.01.06, 01:46
Откуда: Симферополь

Re: Фильтры в rules() модели

Сообщение Faenir »

Уже флуд пошел какой-то. Я при своем мнении останусь: мешанина в одном методе разного функционала, который еще и зависит от порядка размещения - ни есть хорошо. Не зря эта тема поднимается уже не впервые, видимо что-то все же не так...
Nerf
Сообщения: 780
Зарегистрирован: 2015.01.29, 00:37

Re: Фильтры в rules() модели

Сообщение Nerf »

Faenir писал(а): 2017.01.18, 02:01 Уже флуд пошел какой-то. Я при своем мнении останусь: мешанина в одном методе разного функционала, который еще и зависит от порядка размещения - ни есть хорошо. Не зря эта тема поднимается уже не впервые, видимо что-то все же не так...
Вы уж определитесь, что вас не устраивает: идеология или порядок выполнения... С последним все ок.
ПС: Ну можете писать в обратном порядке return array_reverse([...], true) :lol:
Аватара пользователя
Faenir
Сообщения: 292
Зарегистрирован: 2010.01.06, 01:46
Откуда: Симферополь

Re: Фильтры в rules() модели

Сообщение Faenir »

Зачем определяться, если оно не устраивает в комплексе? Были бы валидаторы отдельно - было бы пофиг на порядок.
ПС: отличная шутка
Аватара пользователя
ElisDN
Сообщения: 5845
Зарегистрирован: 2012.10.07, 10:24
Контактная информация:

Re: Фильтры в rules() модели

Сообщение ElisDN »

Faenir писал(а):Зачем определяться, если оно не устраивает в комплексе?
Привыкайте. Yii - это изначально RAD фреймворк, где скорость разработки "фигак и в продакшен" и экономия строк важнее архитектуры.
Леонид
Сообщения: 54
Зарегистрирован: 2017.01.05, 00:20

Re: Фильтры в rules() модели

Сообщение Леонид »

Faenir писал(а): 2017.01.17, 00:28 Я верно понял, что валидаторы исполняются тупо по очереди и если вставить фильтр после валидаторов, то он не будет принимать участия в предыдущих валидаторах?

Пример, который протестил только что.
Создаю запись 'slug' = 'test', затем создаю запись 'slug' = ' test ' (с пробелами, для теста trim).
Два варианта rules():

Код: Выделить всё

    // вариант 1
    return [
        ['slug', 'trim'],
        ['slug', 'unique']
    ];

    // вариант 2
    return [
        ['slug', 'unique'],
        ['slug', 'trim']      
    ];
Вариант 1 - все ок, ошибка в форме.
Вариант 2 - форма проходит валидацию, после получаю ошибку бд (SQLSTATE[23000]: Integrity constraint violation: 1062 Duplicate entry 'test' for key 'slug'). Не было бы уникального ключа в бд - спокойно записались бы дубликаты, т.к. trim все же применяется, но уже после валидации.

Собственно к чему я это... довольно не очевидный момент, с возможно печальными последствиями. В доках нигде не нашел инфу про это. Часто встречаю на гитхабе именно второй вариант использования. Да что далеко ходить... вот dektrium/yii2-user знаменитый: https://github.com/dektrium/yii2-user/b ... r.php#L235
Напишите свой фильтр и юзайте его например так [['title'], 'filter', 'filter' => '\common\filters\FilterModel::trimAndStripTags'], тогда не нужно будет заморачиваться что первым должно идти, с HtmlPurifier + trim +required такая же петрушка, если юзать стандартные фильтры и валидаторы, то нужно в строго определённом порядке выстраивать правила. Но стандартные на то и стандартные - для большинства случаев подходят. В общем не нравится что то, никто не запрещает написать свой велосипед под конкретный случай.

П.С. Может способ и не по феншую, зато удобно)
Аватара пользователя
maleks
Сообщения: 1985
Зарегистрирован: 2012.12.26, 12:56

Re: Фильтры в rules() модели

Сообщение maleks »

Леонид , вы не верно поняли диллему ТС, самое время с ней разобраться и вам, т.к. поверхностные знания работы фреймворка чреваты.
Yii2 universal module sceleton - for basic and advanced templates
Nerf
Сообщения: 780
Зарегистрирован: 2015.01.29, 00:37

Re: Фильтры в rules() модели

Сообщение Nerf »

Faenir писал(а): 2017.01.18, 09:25 Зачем определяться, если оно не устраивает в комплексе? Были бы валидаторы отдельно - было бы пофиг на порядок.
ПС: отличная шутка
Нет, не пофиг. Порядок важен в любом случае, до вас это не доходит никак.
Пример. Вам нужно проверить email на корректность и на уникальность:
a) email -> unique - ок
б) unique -> email - не ок, если это не email, то запрос излишен.

ПС: Вы прочитали тему с обсуждением другой проблемы, ничего не поняли и начали гнуть свою линию...
Леонид
Сообщения: 54
Зарегистрирован: 2017.01.05, 00:20

Re: Фильтры в rules() модели

Сообщение Леонид »

maleks писал(а): 2017.01.18, 16:04 Леонид , вы не верно поняли диллему ТС, самое время с ней разобраться и вам, т.к. поверхностные знания работы фреймворка чреваты.
Ну как это, тс пишет как раз о том, что только выстроив в определённом порядке правила получает то что ему нужно

То же самое с htmlPurifier я как раз сказал что в случае если брать необходимую последовательность, то пример c Purifier очень похож тем что тут тоже нужна строгая последовательность и это тоже не указано доках (думаю потому что это логично, поэтому и не указано)))). И к этому я пришёл как раз когда разбирался с правилами валидации

Если нужно что бы поле было заполнено без xss без пробелов с краёв и что бы в результате было не пустым и всё было правильно то нужно сначала пускать htmlPurifir, трим, а затем только required иначе при введении <script></script> запишется пустота, а если сначала пропустить через Purifier а затем через required, то такой трюк уже не пройдёт, вот что бы не писать три строки, да ещё и в строго определённом порядке я написал свой фильтр, который делает тоже самое, но только в одну строку. В конце концов фреймворк не настаивает что бы использовались только его фильтры, раз есть возможность написать свои фильтры\правила.

Где я ошибся? Если брать в расчёт именно то что даёт фреймворк.

П.С. Читать как бы умею и заметьте я сказал что ситуация аналогична ситуации тс.

П.С.П.С, Вы бы указали что именно я сделал не так, запилив свой фильтр который сразу заменяет трим, проверку на пустоту и вырезание тэгов, что я этим нарушил. При условии что мне требуется вместе все три обработки делать часто. Толку от Вашего поста было бы больше намного вместо того что бы назвать неумехой, Вам не кажется?)
Последний раз редактировалось Леонид 2017.01.18, 19:07, всего редактировалось 6 раз.
Закрыто