За последние 24 часа нас посетили 47495 программистов и 1806 роботов. Сейчас ищут 1119 программистов ...

Редирект в MVC

Тема в разделе "PHP для новичков", создана пользователем feelz, 5 июн 2018.

  1. feelz

    feelz Новичок

    С нами с:
    22 авг 2017
    Сообщения:
    10
    Симпатии:
    0
    Добрый день, уважаемые коллеги.
    Взялся за освоение концепта MVC и не могу найти ответ на такой вопрос - как сделать переадресацию в этой структуре? Допустим, контроллер подключил модель, модель провела некоторые действия, по результату которых нужно перейти по новой ссылке. Header, понятное дело, не сработал бы, JS-овский window.location тоже пользы не принес. Итог - 404 страница.
    Более чем уверен, что тут все дело в маршрутах, в самой сути MVC, и я не до конца разобрался в этом, но может быть, предусмотрены какие-то приемы редиректа и задания ссылки из контроллера/модели?
     
    #1 feelz, 5 июн 2018
    Последнее редактирование: 5 июн 2018
  2. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Модель не должна редиректить, она должна обработать данные и вернуть результат. Редирект - задача контроллера. Но редирект делается так же, как и вообще в PHP - через header, или средствами фреймворка (если используется фреймворк). Но, по по большому секрету, фреймворки тоже header делают :)
     
    feelz нравится это.
  3. Sergey_Tsarev

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

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105
    почему? Он не сработает, только если ты что-то выведешь на страницу перед ним.
     
  4. feelz

    feelz Новичок

    С нами с:
    22 авг 2017
    Сообщения:
    10
    Симпатии:
    0
    Спасибо за ответ, поразмыслив, нашел свою ошибку. Но почему из модели нельзя переадресовывать? Ведь и из контроллера, и из модели это получилось одинаково. Только ли из соображений идеологии и эстетичности?
     
  5. acho

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

    С нами с:
    28 дек 2016
    Сообщения:
    854
    Симпатии:
    210
    Адрес:
    Санкт-Петербург
    да. Сам принцип MVC подразумевает то, что в модели только бизнес-логика. Такой подход не с неба появился, это не просто прихоть, а необходимость. Согласись, когда лезешь в большой проект, который написан по какой-либо идеологии, ты ожидаешь увидеть эту самую идеологию. А не искать баг, а он почему-то вдруг в другом месте находится
     
    feelz нравится это.
  6. feelz

    feelz Новичок

    С нами с:
    22 авг 2017
    Сообщения:
    10
    Симпатии:
    0
    Хорошо, тогда еще пару вопросов для полноты понимания картины: запись данных о сервере, проверка его состояния и авторизация - входят в бизнес-логику? Или это прерогатива контроллера?
    Можно ли отталкиваться от суждения, что бизнес-логика - это процедуры и данные, которые особенно важно скрыть, спрятав в модель?
     
  7. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Слой модели - работа с данными, хранилищем, рассчётами
    Слой контроллера - работа с пользовательскими запросами, сессиями, куками и прочим, т.е. взаимодействие с пользователем
    Слой представление - работа с отображением информации, в случае PHP - с вёрсткой
     
  8. glorsh66

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

    С нами с:
    9 июл 2017
    Сообщения:
    247
    Симпатии:
    4
    Ну например следуя реализации MVC в codeigniter -
    Модель - отвечает только за данные. Т.е. берет из базы данных, обрабатывает их (но не готовит к выводу)
    Контроллер - все что связывает данные и представления. Как рас это по сути является адресом который вводит пользователь.
    Представление - кусок сайта, в который контроллер передает параметром данные и возвращается отформатированные данные.

    запись данных о сервере - модель
    проверка его состояния - модель, но можно и в контролере.
    авторизация - контроллер. (но в модели можно искать пользователя и вернуть найденные данные в котроллер, если такой пользователь существует).
     
  9. feelz

    feelz Новичок

    С нами с:
    22 авг 2017
    Сообщения:
    10
    Симпатии:
    0
    А дело заключается вот в чем.
    Есть функция контроллера, которая поэтапно проводит следующие действия:
    - проверяет наличие файла с записанным в него адресом сервера. Если его нет, выводится форма запроса;
    - при выполнении первого условия проверяется статус сервера, есть ли там авторизация;
    - если предыдущий шаг возвращает ошибку 401, выводится форма с логином и паролем;
    - если введенные данные верны - переадресация на другую страницу, если нет - страница со всплывающим окошком выводит ошибку.
    PHP:
    1. <?
    2. public function checkSource()
    3.     //проверяет, доступен ли сервер, введены ли корректные данные
    4.     {
    5.         //проверяем наличие файла с источником
    6.         if(file_exists(ROOT . '/' . Src::FILENAME)) {
    7.             //используя функцию, проверяем, возвращает ли сервер статус 401
    8.             if ($this->get_http_response_code(Src::REPORTSRV) == false) {
    9.             //если 401 - выводится форма авторизации
    10.                 if (!(isset($_POST['login']) && isset($_POST['password']))) {
    11.                 $this->view->generate('auth_view.php', 'template_message_view.php');
    12.                 } else {
    13.                 $log = $_POST['login'];
    14.                     $pass = $_POST['password'];
    15.                     //читаем заголовки
    16.                     $check = $this->checkLogin($log, $pass);
    17.                     switch($check) {
    18.                         case 400:
    19.                         case 403:
    20.                         case 404:
    21.                         case 500:
    22.                         case 502:
    23.                         case 503:
    24.                         case 504:
    25.                             //вывод различных ошибок
    26.                             $this->view->generate('error_view.php', 'template_message_view.php');
    27.                             break;
    28.                         case 401:
    29.                             $this->view->generate('error_view.php', 'template_message_view.php');
    30.                             break;
    31.                         case 200:
    32.                             //header("Location: /rupture) здесь не срабатывает, поскольку заголовки уже отправлены (Cannot modify headers)
    33.                             //JS вполне успешно переводит на искомую страницу, но нужно как-то изящно передать данные сессии
    34.                             ?>
    35.                             <script type="text/javascript">
    36.                             window.location = "/test5/rupture";
    37.                             </script>
    38.                     <?
    39.                             break;
    40.                     }
    41.                 }
    42.             }
    43.         }
    44.         else {
    45.             $this->view->generate('get_srv_view.php', 'template_message_view.php');
    46.             if(isset($_POST['prs'])) {
    47.             file_put_contents(ROOT . '/src/src.txt', $_POST['prs']);
    48.             }
    49.         }
    50.     }
    51. }
    Вопрос в том, как сделать редирект header'ом, не прибегая к JS. Собственно, с уже отправленными заголовками не удается ни создать сессию, ни изменить headers. А помимо моих страниц с формами, заголовки задает единая точка входа - index.php инклудит файлы контроллера, модели, представления, то есть все это дело идет корнями с самого начала.

    Как можно обойти эти проблемы?
     
    #9 feelz, 7 июн 2018
    Последнее редактирование: 7 июн 2018
  10. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Когда php пишет "Cannot modify headers", он обычно указывает, где начался вывод. Если он это пишет в MVC, то что-то сильно не так, поскольку никакого вывода быть не должно, пока не отработает контроллер. Ищи, BOM может где схватил
    --- Добавлено ---
    P.S. Логика какая-то чрезвычайно странная
     
  11. Sergey_Tsarev

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

    С нами с:
    17 мар 2016
    Сообщения:
    502
    Симпатии:
    105
    @feelz, а у тебя маршрутизатор присутствует?
     
  12. feelz

    feelz Новичок

    С нами с:
    22 авг 2017
    Сообщения:
    10
    Симпатии:
    0
    Да, присутствует.
    --- Добавлено ---
    Спасибо за наводку, думал, что меня это обошло, но нет, и правда bom обнаружился. Теперь бы понять, как сессии передавать...
     
  13. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Куда передавать? На другие сайты?
     
  14. feelz

    feelz Новичок

    С нами с:
    22 авг 2017
    Сообщения:
    10
    Симпатии:
    0
    Нет. Инициировать сессию и передавать ее данные внутри архитектуры приложения. Неочевидно, в какой форме ее принято представлять в MVC - в виде отдельного класса, модели, или вообще метода класса.
     
  15. mkramer

    mkramer Суперстар
    Команда форума Модератор

    С нами с:
    20 июн 2012
    Сообщения:
    8.600
    Симпатии:
    1.764
    Ну обычно это просто отдельный класс, экземпляр кладётся в какой-нибудь DI-контейнер, или в реестр, или в ServiceLocator, и достаётся, когда нужен. MVC не означает, что каждый твой класс должен относиться к какой-то букве, могут быть просто классы служебного назначения
     
    #15 mkramer, 11 июн 2018
    Последнее редактирование: 11 июн 2018
    AlexProg нравится это.