Добрый день, уважаемые коллеги. Взялся за освоение концепта MVC и не могу найти ответ на такой вопрос - как сделать переадресацию в этой структуре? Допустим, контроллер подключил модель, модель провела некоторые действия, по результату которых нужно перейти по новой ссылке. Header, понятное дело, не сработал бы, JS-овский window.location тоже пользы не принес. Итог - 404 страница. Более чем уверен, что тут все дело в маршрутах, в самой сути MVC, и я не до конца разобрался в этом, но может быть, предусмотрены какие-то приемы редиректа и задания ссылки из контроллера/модели?
Модель не должна редиректить, она должна обработать данные и вернуть результат. Редирект - задача контроллера. Но редирект делается так же, как и вообще в PHP - через header, или средствами фреймворка (если используется фреймворк). Но, по по большому секрету, фреймворки тоже header делают
Спасибо за ответ, поразмыслив, нашел свою ошибку. Но почему из модели нельзя переадресовывать? Ведь и из контроллера, и из модели это получилось одинаково. Только ли из соображений идеологии и эстетичности?
да. Сам принцип MVC подразумевает то, что в модели только бизнес-логика. Такой подход не с неба появился, это не просто прихоть, а необходимость. Согласись, когда лезешь в большой проект, который написан по какой-либо идеологии, ты ожидаешь увидеть эту самую идеологию. А не искать баг, а он почему-то вдруг в другом месте находится
Хорошо, тогда еще пару вопросов для полноты понимания картины: запись данных о сервере, проверка его состояния и авторизация - входят в бизнес-логику? Или это прерогатива контроллера? Можно ли отталкиваться от суждения, что бизнес-логика - это процедуры и данные, которые особенно важно скрыть, спрятав в модель?
Слой модели - работа с данными, хранилищем, рассчётами Слой контроллера - работа с пользовательскими запросами, сессиями, куками и прочим, т.е. взаимодействие с пользователем Слой представление - работа с отображением информации, в случае PHP - с вёрсткой
Ну например следуя реализации MVC в codeigniter - Модель - отвечает только за данные. Т.е. берет из базы данных, обрабатывает их (но не готовит к выводу) Контроллер - все что связывает данные и представления. Как рас это по сути является адресом который вводит пользователь. Представление - кусок сайта, в который контроллер передает параметром данные и возвращается отформатированные данные. запись данных о сервере - модель проверка его состояния - модель, но можно и в контролере. авторизация - контроллер. (но в модели можно искать пользователя и вернуть найденные данные в котроллер, если такой пользователь существует).
А дело заключается вот в чем. Есть функция контроллера, которая поэтапно проводит следующие действия: - проверяет наличие файла с записанным в него адресом сервера. Если его нет, выводится форма запроса; - при выполнении первого условия проверяется статус сервера, есть ли там авторизация; - если предыдущий шаг возвращает ошибку 401, выводится форма с логином и паролем; - если введенные данные верны - переадресация на другую страницу, если нет - страница со всплывающим окошком выводит ошибку. PHP: <? public function checkSource() //проверяет, доступен ли сервер, введены ли корректные данные { //проверяем наличие файла с источником if(file_exists(ROOT . '/' . Src::FILENAME)) { //используя функцию, проверяем, возвращает ли сервер статус 401 if ($this->get_http_response_code(Src::REPORTSRV) == false) { //если 401 - выводится форма авторизации if (!(isset($_POST['login']) && isset($_POST['password']))) { $this->view->generate('auth_view.php', 'template_message_view.php'); } else { $log = $_POST['login']; $pass = $_POST['password']; //читаем заголовки $check = $this->checkLogin($log, $pass); switch($check) { case 400: case 403: case 404: case 500: case 502: case 503: case 504: //вывод различных ошибок $this->view->generate('error_view.php', 'template_message_view.php'); break; case 401: $this->view->generate('error_view.php', 'template_message_view.php'); break; case 200: //header("Location: /rupture) здесь не срабатывает, поскольку заголовки уже отправлены (Cannot modify headers) //JS вполне успешно переводит на искомую страницу, но нужно как-то изящно передать данные сессии ?> <script type="text/javascript"> window.location = "/test5/rupture"; </script> <? break; } } } } else { $this->view->generate('get_srv_view.php', 'template_message_view.php'); if(isset($_POST['prs'])) { file_put_contents(ROOT . '/src/src.txt', $_POST['prs']); } } } } Вопрос в том, как сделать редирект header'ом, не прибегая к JS. Собственно, с уже отправленными заголовками не удается ни создать сессию, ни изменить headers. А помимо моих страниц с формами, заголовки задает единая точка входа - index.php инклудит файлы контроллера, модели, представления, то есть все это дело идет корнями с самого начала. Как можно обойти эти проблемы?
Когда php пишет "Cannot modify headers", он обычно указывает, где начался вывод. Если он это пишет в MVC, то что-то сильно не так, поскольку никакого вывода быть не должно, пока не отработает контроллер. Ищи, BOM может где схватил --- Добавлено --- P.S. Логика какая-то чрезвычайно странная
Да, присутствует. --- Добавлено --- Спасибо за наводку, думал, что меня это обошло, но нет, и правда bom обнаружился. Теперь бы понять, как сессии передавать...
Нет. Инициировать сессию и передавать ее данные внутри архитектуры приложения. Неочевидно, в какой форме ее принято представлять в MVC - в виде отдельного класса, модели, или вообще метода класса.
Ну обычно это просто отдельный класс, экземпляр кладётся в какой-нибудь DI-контейнер, или в реестр, или в ServiceLocator, и достаётся, когда нужен. MVC не означает, что каждый твой класс должен относиться к какой-то букве, могут быть просто классы служебного назначения