За последние 24 часа нас посетили 17503 программиста и 1650 роботов. Сейчас ищут 899 программистов ...

Где производить валидацию данных в контроллере или в модели?

Тема в разделе "Прочие вопросы по PHP", создана пользователем hardj, 17 ноя 2009.

  1. hardj

    hardj Активный пользователь

    С нами с:
    17 ноя 2009
    Сообщения:
    9
    Симпатии:
    0
    Интересует мнение сообщества по следующему вопросу. Разрабатывается веб-сайт с использованием MVC, интересует вопрос где производить проверку данных пришедших от пользователя на валидность. В модели или в контроллере и конечно объясните своё мнение.
     
  2. Костян

    Костян Активный пользователь

    С нами с:
    12 ноя 2009
    Сообщения:
    1.724
    Симпатии:
    1
    Адрес:
    адуктО
    Проводи, где тебе удобнее. Ты программист или копипастер?
    "Где удобнее" подразумевает, то, что ты не будешь после этого делать больше костылей, где ты будешь смотреть на код и он будет радовать глаз и ты будешь кайфовать, смотря на валидацию.
     
  3. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Валидация это принадлежность модели. Только она знает что ей нужно и в каком виде.

    Но вызывать валидацию должен тот кто пользуется моделью, т.е. контроллер.

    Здесь форма выступает простейшей моделью. Вместо нее(или после нее) может быть Domain модель.
    PHP:
    1.  
    2. <?php
    3. class UserController extends Zend_Controller_Action {
    4.     public formAction() {
    5.         $frm = new My_Form();
    6.         if ($this->getRequest()->isPost()) {
    7.             if ($frm->isValid($this->getRequest()->getPost()) {
    8.  
    9.             }
    10.         }
    11.     }
    12. }
    Естественно, если кто-то другой(не контроллер) будет использовать нашу модель, то и он может использовать валидацию модели.
     
  4. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    зависит от сложности валидации, если сложная - то в модели, если простая - то в контроллере
     
  5. hardj

    hardj Активный пользователь

    С нами с:
    17 ноя 2009
    Сообщения:
    9
    Симпатии:
    0
    Допустим есть такая ситуация: есть товар соответственно есть его модель которая связана с таблицей характеристик о товаре. К данному товару относится несколько изображений (число не известно) - соответственно имеется другая модель (изображения) которая связана с таблиецей изображений (в ней хранится id товара и id изображения). Сами файлы изображений сохраняются в папке на диске и обзываются id.jpg.

    Нам нужно проверить правильный ли тип файла загрузил пользователь и все ли обязательные характеристики указал у товара. Получается в модели товара мы устанавливаем правила валидации (обязательно должно быть заполненно название). В модели изображений никаких правил мы не можем указать (ей то побарабану какой файл пришёл) она должна просто вставить запись в таблицу с Id товара и получить Id изображения которое сгенерировалось как autoincrement. Получается проверять тип файла будет контроллер. В итоге имеем два типа валидации (одна в контроллере другая в модели). Не логично бы вынести валидацию в контроллер и не прыгать по между ним и контроллером при написании кода (изменении правил валидации)?
     
  6. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    проверяет модель товаров
     
  7. [vs]

    [vs] Суперстар
    Команда форума Модератор

    С нами с:
    27 сен 2007
    Сообщения:
    10.559
    Симпатии:
    632
    Если MVC правильная, то должна валидировать и приводить в нужный вид данные модель. Это как клиент-сервер, где контроллер - клиент.
     
  8. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    [vs]
    мвц чисто правильно никогда не делают, иначе бред будет, что ты даже любые самые мелкие проверки и действия обязан будешь выносить в модель
     
  9. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.339
    Симпатии:
    44
    Нет одного решения. Обычно проверки размазаны - часть в модели, часть в контроллере. В модели сидят проверки относительно данных самой модели и вызываются они обычно на (условно) onBeforeSave событии. Как правило в фреймворках есть уже готовые решения для создания валидаторов методом описания условий.

    А вот проверки на связность данных - в контроллер. Например, объект фирмы имеет связь с объектом города - тут никак не запихнуть проверку города в модель. Для себя стараемся придерживаться такого правила - модель не должна ничего знать про другие модели. Т.е. внутри модели не должно быть никаких созданий/вызовов объектов других моделей. Следует это из правила уменьшения сцепок.

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

    Как правило, условно можно разделить модели на прикладные и самодостаточные. Например, фото - это исключительно прикладная модель, с которой мы можем работать изнутри той модели которой эти картинки нужны. А вот, к примеру, модель города - это уже самодостаточная модель, которая связана с другими - работа с ней должна идти в контроллере. Опять же сложно описать критерии - когда можно, когда нет... все порой на интуиции, которая является следствием опыта.

    В случае изображений мы поступили так: есть некий класс "коллекция файлов", который по сути является неким датамапером для работы с изображениями. Он умеет по имени модели строить путь и возвращать набор объектов изображений, а так же умеет делать "save" в т.ч. из uploaded фалов. Для каждой модели, которая работает с изображениями есть соответствующая модель картинки (наследованная от общей, конечно) - всякие проверки на форматы, ресайзы и т.д. уже в ней. Т.е. по сути в модели товаров у нас только Toolkit::instance()->getCollection()->uploadFiles("МодельИзображенийДляТоваров"). Колекция же по сути делает для каждого файла new "МодельИзображенийДляТоваров" и потом этому объекту save(), а тот уже на save() делает все, что нужно.
     
  10. hardj

    hardj Активный пользователь

    С нами с:
    17 ноя 2009
    Сообщения:
    9
    Симпатии:
    0
    Всем спасибо за обсуждение. Понял для себя что в зависимости от ситуации надо использовать. Хотя так и думал, просто хотелось чтобы валидация проходила в одном месте и не прыгать от файла к файлу. Получается что так может получится только если проводить её в контроллере. Но по логике она должна делаться в модели (примеры из постов это подтверждают) следовательно будем смотреть на ситуацию и делать проверки в зависимости от неё.
     
  11. iliavlad

    iliavlad Активный пользователь

    С нами с:
    24 янв 2009
    Сообщения:
    1.689
    Симпатии:
    4
    если у вас есть/будет пример, где данные модели надо валидировать в контроллере, напишите сюда, пожалуйста.
     
  12. hardj

    hardj Активный пользователь

    С нами с:
    17 ноя 2009
    Сообщения:
    9
    Симпатии:
    0
    Ок, договорились. Сейчас пересмотрел ситуация с файлами изображения и понял, что валидацию можно вынести в модель. Следовательно пока такого примера нет. Если появится обязательно напишу. Ну ждём таких примеров от участников обсуждения.
     
  13. Костян

    Костян Активный пользователь

    С нами с:
    12 ноя 2009
    Сообщения:
    1.724
    Симпатии:
    1
    Адрес:
    адуктО
    iliavlad
    у меня данные валидируются в контроллере ибо модель требует корректный данных. Я всегда валидирую данные на входе потому как не хочу чтобы левые данные где-то блуждали еще пока не пройдут валидацию где-то в модели. Смысл? Один хрен контроллер отправляет в другую степь если данные не такие как надо, зачем именно в модели их проверять? Ну может так и надо, но мне удобнее по моему, а "если нет разницы зачем платить больше"?
     
  14. sylex

    sylex Активный пользователь

    С нами с:
    9 ноя 2008
    Сообщения:
    625
    Симпатии:
    0
    Адрес:
    Омск
    Костян
    а контроллеров несколько может быть в разных частях сайта - поэтому удобнее по-моему в модели... в модель отдал данные, и не паришься, валидные они или нет - она "разберется"

    хотя некоторые моменты допустимо проверять в контроллере
     
  15. iliavlad

    iliavlad Активный пользователь

    С нами с:
    24 янв 2009
    Сообщения:
    1.689
    Симпатии:
    4
    мясо надо)
    что за модель? что у нее за данные, которые должны быть корректными на входе (даже скорее перед входом)? используется еще где-то? как обойти дублирование кода ("зачем платить больше"), если модель используется еще где-то и данные снова должны быть корректные? менялась ли модель в процессе разработки? если да, как вы отслеживали, что в контроллере и других местах использования модели все данные валидировались?

    извиняюсь, что много вопросов.
     
  16. Костян

    Костян Активный пользователь

    С нами с:
    12 ноя 2009
    Сообщения:
    1.724
    Симпатии:
    1
    Адрес:
    адуктО
    Да ниче - ответ один, как для тебя так и для sylex - я юзаю что-то типа command или вроде точнее reactor, поэтому как таковое понятие контроллера у меня размыто немного и код не дублируется, просто один контроллер обращается как бы к другому... В принципе это уже не совсем контроллер с ваших точек зрения, но кроме как он больше никто делами контроллера не занимается.... От така фигня ))
     
  17. alexey_baranov

    alexey_baranov Активный пользователь

    С нами с:
    3 фев 2009
    Сообщения:
    647
    Симпатии:
    0
    Адрес:
    Сургут
    hardj
    Все на эксепшенах и все в моделях. Потому что модель используется и внутри других моделей и в кроновских скриптах и в веб-сервисах. А контроллеров там не будет. Так что вот и подумай.
     
  18. hardj

    hardj Активный пользователь

    С нами с:
    17 ноя 2009
    Сообщения:
    9
    Симпатии:
    0
    В вашем случае понятно. ПРосто пока не сталкивался с необходимостьюв кроне использовать модели. Да и используя MVC разрабатываю недавно. Поэтому и интересуют фундаментальные вопросы.
     
  19. iliavlad

    iliavlad Активный пользователь

    С нами с:
    24 янв 2009
    Сообщения:
    1.689
    Симпатии:
    4
    hardj
    пока не привели пример с необходимостью валидации данных в контроллере, можешь валидировать всё в модели)
     
  20. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Проверять ты можешь где угодно.
    Но метод валидации предоставляет модель.
    Только она может знать что ей нужно и в каком виде.

    PHP:
    1. <?php
    2. class UserController extends Zend_Controller_Action {
    3.     public function updateAction() {
    4.         $mdl = new Model();
    5.         if (!$mdl->isValid($this->getRequest()->getParams())) {
    6.             die("Все пропало шеф!");
    7.         }
    8.     }
    9. }
    глупости какие


    Bingo!
     
  21. alexey_baranov

    alexey_baranov Активный пользователь

    С нами с:
    3 фев 2009
    Сообщения:
    647
    Симпатии:
    0
    Адрес:
    Сургут
    b]Simpliest[/b]
    По-моему в кроновском скрипте нет ни url ни request, но конечно можно их искуственно создать, если по-другому никак.

    hardj
    кстати когда модель приучена к контролеру, только так и остается поступать, чтобы чего-то от нее добиться. Это надо эмулировать запрос, запустить целый паровоз из раутер - диспечер - контролер и заблудиться в нем, чтобы в конце концов прийти в акшен, который только и нужет был. это получается программировать мвц, чтобы повторить ту ошибку, от которой учит мвц.

    когда модель чистая, всегда остаатся возможность писать код без контролеров и вьюшек. например служебный скрипт такого вида
    PHP:
    1. <?php
    2. $model= new Model();
    3. $model->a= $argv[1];
    4. $model->doSomething();
    5.  
    Если в doSomthing() у тебя модель ожидает, что в ней провалидированные контролером данные, считай ты приучил ее к контролеру. А зачем тебе тогда мвц?
     
  22. Костян

    Костян Активный пользователь

    С нами с:
    12 ноя 2009
    Сообщения:
    1.724
    Симпатии:
    1
    Адрес:
    адуктО
    кто такое сказал? Это доказано как закон? Или может аксиома?
    Без всяких упрёков к тебе, но поначитаются авторитетных авторов, которые навяжут вам свое мнение, а потом рассказывают, что да как надо. Всё программирование заканчивается на Макконнелле. Выше уже специализация.
     
  23. alexey_baranov

    alexey_baranov Активный пользователь

    С нами с:
    3 фев 2009
    Сообщения:
    647
    Симпатии:
    0
    Адрес:
    Сургут
    Иногда правильно и в контролере. валидация тоже бывает разной. есть валидация уровня бизнеслогики, есть валидация уровня интерфейса. но это совсем другой случай.

    например если есть модель, которая делит два числа
    class DivModel{
    fnc div(inx x, int y){ }
    }

    если в скрипте то все понятно. если эту же модель использовать через веб-нитерфейс, то появляется дополнительная валидация.

    валидация у!=0 - это валидация уровня бизнеслогики и она правильно делаться внутри модели, а не в каком-то контролере. А валидацию x и y - это два чиста, а не две строки 'qwerty' можно/нужно делать внутри контролера, потому что это не относится к бизнеслогике.

    и все везде всегда на исключениях
     
  24. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    URI - это адрес ресурса с параметрами и ничего более.

    чем отличается
    GET /localhost/cli.php?param=1
    от
    php.exe D:\www\cli.php param=1

    Да ничем. Единственное что PHP для тебя распарсит параметры и создаст $_GET/$_POST/$_COOKIE
    Для CLI у тебя эти параметры будут в $argv, а в $argc будет их число.
    Все.

    Слушай, завязывай а? Я терпеть не могу глупости.

    Модель вообще ни к чему не приучена. Она получает данные и может с ними что-то сделать.

    PHP:
    1.  
    2. <?php
    3. $mdl = new Model();
    4. $mdl->isValid($argv);
    5. $mdl->isValid($_POST);
    6. $mdl->isValid(array('param' =>1));
    Но о других моделях она знать ничего не знает и не должна.

    Поэтому этот паровоз как ты изволил выразится вызван одним простым принципом DRY - don't repeat yourself
    Дабы не страдать маразмом и не прописывать связи и бизнеслогику отдельно для CLI версии, пишется вот такой раннер
    и используется уже готовый код.
     
  25. Simpliest

    Simpliest Активный пользователь

    С нами с:
    24 сен 2009
    Сообщения:
    4.511
    Симпатии:
    2
    Адрес:
    Донецк
    Это логика сказала. Вы ее не слушаете?

    Кроме меня самого никто не знает люблю я картошку-фри или бешбармак.
    Поэтому и говорить нравится/ненравится valid/not-valid - мне, а не тебе.
    Ты можешь у меня спросить, но не более того.
    Потому что завтра вкусы у меня изменятся, а ты по-прежнему будешь уверен что бешбармак и блондинки это то, что мне нужно.

    Ты заблуждаешься.

    Знаешь в чем твоя проблема?
    В том, что ты наивно полагаешь, что мне можно навязать мнение одним лишь авторитетом.

    Я не читал ни одной книги по программированию за последние 17 лет, но с логикой я дружу.
    И мне будет плевать на Фаулера, Макконела и других, если они начнут нести чушь.

    И не надо говорить глупости, я этого не люблю.