MVC и валидация

Василий М.

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

Про активных и пассивных сам придумал? =).
нет, кто-то дописал.
 

WMix

герр M:)ller
Партнер клуба
Василий М.
ничего личного, но пример наиужаснейший. по мне этот пример на много понятнее и неплохо описывает MVC буквально на пальцах
 

WMix

герр M:)ller
Партнер клуба
PHP:
/* простой контроллер */
$pagetitle = "Ссылки";
$DATA=dbgetarr("SELECT * FROM links"); // работа с моделью
if ($DATA === FALSE) error500();
include "tpl_main.php"; // представление
без ооп ДА, но все разделено.
 

Василий М.

Новичок
К чему этот пример? Он иллюстрирует тему шаблонов, к MVC он не имеет никакого отношения.
но все разделено
Задача MVC - не разделять, а сделать так, что бы система инкапсулировала в моделях бизнес-логику, не давая ей мигрировать по скриптам как г-но по весенним тротуарам.
Это - основная задача MVC.
Ибо когда логика у нас не размазана по контроллерам (скриптам), а представлена в разных слоях системы, то поддержка и прозрачность такого кода становится в разы качественнее.
В примере выше это как раз не MVC, а будущий ТТУК. Тут как написано в Википедии - контроллер использует DBAL и делает вид, что это модель.
Это - не модель.
Модель - это сущность, описывающая что-то в системе. Это совокупность правил. И CRUD в моделях - это лишь способность сохранять эту логику в БД.
Не надо из функции dbgetarr() делать модель. Это лишь слой взаимодействия с базой, не более.
 

WMix

герр M:)ller
Партнер клуба
не понимаю чем
PHP:
$result = $this->getDbTable()->find($id);
или
PHP:
$db->select()->from(array('p' => 'products'), array('product_id', 'product_name'))
->join(array('l' => 'line_items'),'p.product_id = l.product_id');
из зенда другой чем
PHP:
dbgetarr("SELECT * FROM links");
конечно можно этот код запрятать в $list->getList(), но сути не меняет, в таком минималистическом представлении, это очень даже MVC. спорить не хочу, хотел только намекнуть что твой пример многословен, а описывает только одну из 3х составляющих,
но наоборот очень респектирую твой труд!
 

Василий М.

Новичок
все эти примеры - это уровень оперирующий БД.
Модель же - это не только слой для CRUD
$result = $this->getDbTable()->find($id);
получает чистые данные
у меня же, например,
получает список объектов моделей, в которых содержится вся бизнес-логика этих сущьностей.
в этом и разница.
 

fixxxer

К.О.
Партнер клуба
Без ООП и без ТТУК будет как-то так... :)
PHP:
function render($tpl, $view) {
    extract($view);
    include "tpl_main.php";
}   

function loadLinks(&$view) {
    $view = dbgetarr("SELECT * FROM links");
}   

$view = array();
loadLinks($view['links']);
render("tpl_links.php", $view);
 

WMix

герр M:)ller
Партнер клуба
нет с этим $list->getList() как раз все отлично а вот Krugozor, Advert, Common, Pagination, Manager, List, Common это так много различных слов и спрашиваешь себя, о чем это?
$this->createNotification() ->setMessage($this->getView()->lang['notification']['forbidden_access']) и тд. почемуб обычный здравствуй мир не написать, хоть даже без базы данных, но простой понятный скриптик
 

hell0w0rd

Продвинутый новичок
По моему мнению валидация - это не отдельно V - это все то же M.
Потому как валидацию проходят сущности, которые мы потом записываем на сервер. Будь-то БД, или файловая система. Соответсвенно не важно откуда и как данные поступают - они должны пройти валидацию.
С этой точки зрения шикарно смотрится ОРМ - мы создаем объект любыми средствами, будь-то форма, или еще что-то, а затем превращаем в объект и смотрим - валиден он или нет.
 

stwa

Новичок
Прошу привести пример, где можно отказаться от контроллера.
Не отказаться от контроллера, а сделать контроллер пустым, т.е. ничего не делающим.
Например, первое что пришло в голову - страница вывода списка зарегистрированных пользователей
Я могу в контроллере сделать так:
PHP:
$userCollection = $this->getUserService()->findAll();
$this->view->assign(array('users' => $userCollection));
а потом во view итерировать по коллекции, получать нужные данные и выводить

А могу сделать контроллер вообще пустым, а коллекцию юзеров дергать из view с помощью хелпера (помощника вида).
WMix
Это такой класс, в который я обычно выношу повторяющуюся во многих view логику и т.п.
Помощники вида обычно используются в следующих случаях:
- Доступ к моделям;
- Сложная или повторяемая логика отображения;
- Преобразование и форматирование данных модели;
- Сохранение данных между двумя скриптами вида.
В таком случае во view будет что-то типа этого:
PHP:
<?
$users = $this->getUserList(); //getUserList - это как раз хелпер, который вернет нам уже отформатированную коллекцию пользователей, например в массиве
?>
<table>
<? foreach($users as $user): ?>
    <tr><td><?=$user['name'];?></td></tr>
<? endforeach; ?>
</table>
 

hell0w0rd

Продвинутый новичок
А могу сделать контроллер вообще пустым, а коллекцию юзеров дергать из view с помощью хелпера (помощника вида).
Это не MVC тогда. Модель нифига не знает о том как данные будут интерпретированы. Она знает только что за данные, в каком кол-ве, где, есть ли вообще они, какой у них тип и тд. Сюда же включено то, что модель не умеет ничего экранировать, она хранит данные в сыром виде.
Вид знает что если ему поступят такие данные - то он их выведет так. Но он не знает как и откуда ему поступят эти данные. И должен быть готов к тому что ему поступят не все данные, должен уметь "предохраняться" - экранировать
Ну и контроллер - знает что есть модель и есть представление - он тащит нужные данные и отдает их нужному представлению.
 

vanicon

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

stwa

Новичок
vanicon
все верно, так и происходит, как вы описали
я говорю, что с моделью никаких операций не происходит в контроллере

GusakovNick
я раньше тоже придерживался такого мнения насчет view,
но сейчас все больше склоняюсь к варианту, когда view не только может, но и должна знать о моделе!

Приведу цитаты все из того же поста на хабре (см. ссылку выше), где опубликован перевод уважаемого Падрика

Некоторое время назад я писал проект (Zend_View Enhanced), который рано или поздно будет принят в Zend Framework для внесения объектно-ориентированного подхода в создание сложных представлений, и начал жаловаться на то, что контроллеры являются единственным методом передачи данных из моделей в представления. Я считал, что представления могут обойтись без посредника и использовать вместо него помощников представлений (View Helpers) для чтения данных напрямую из моделей. Это приведет к архитектуре, в которой для многих страниц, доступных только для запросов на чтение, ваше действие контроллера (Controller Action) будет… пустым. В нем не будет никакого кода. Аминь!

Самый лучший контроллер для меня — это отсутствие контроллера.
Никто из возражающих не заметил, что на самом деле это очень старая идея. В Java термин помощник представления ввели много лет назад, как шаблон проектирования в J2EE, показав, что помощники представлений могут помогать представлениям в доступе к моделям (только в чтении, так как все операции записи должны проходить через контроллер!) без посредника-контроллера. Все в MVC говорит о том, что представления должны знать не только о массивах, которые контроллер кладет им в рот, но и о моделях, которые они отображают.

Так почему бы не пойти дальше! Скольким представлениям хватает одной модели? Многие мои представления используют несколько моделей, обращения к которым очень часто повторяются. Помощник представления — это один класс, но для добавления повторяющихся обращений в контроллеры нам надо повторять эти обращения во множестве методов!
Я все чаще ловлю себя на мысли, что пишу в контроллерах практически один и тот же код (дернуть модель, преобразовать данные, отдать во вью)
 

hell0w0rd

Продвинутый новичок
А вы юзайте нормальные шаблонизаторы и все) например twig умеет дергать геттеры. Таким образом контроллеры в симфони выглядят достаточно просто и без излишеств.
 

stwa

Новичок
twig и есть в своем роде хелпер (помощник вида) и если он умеет дергать геттеры модели, то почему вы тогда говорите, что использование помощников вида - это не MVC?
 

vanicon

Новичок
А вы юзайте нормальные шаблонизаторы и все) например twig умеет дергать геттеры. Таким образом контроллеры в симфони выглядят достаточно просто и без излишеств.
php по моему мнению и так является шаблонизатором, и его вполне хватает...
 

hell0w0rd

Продвинутый новичок
twig и есть в своем роде хелпер (помощник вида) и если он умеет дергать геттеры модели, то почему вы тогда говорите, что использование помощников вида - это не MVC?
Вы в контроллере должны создать объект, прежде чем его дернуть. Чтобы спокойно выводить данные объектов было сделано такое решение.
 

fixxxer

К.О.
Партнер клуба
контроллер - знает что есть модель и есть представление - он тащит нужные данные и отдает их нужному представлению.
WRONG.

Это как раз типичное неправильное понимание роли контроллера, о котором Василий М. пытался написать в википедии. Это как раз ТТУК.

Контроллер _связывает_ model и view, об их данных он ничего не знает. Зачем ему знать?
 
  • Like
Реакции: stwa
Сверху