2

Пишу на данный момент MVC приложение на PHP, и возник вопрос по поводу вывода информации, полученной из модели.

На данный момент реализация следующая. Каждый "главный" (вызываемый из контроллера) метод модели возвращает многомерный массив, ключами которого является "тип"(warn, stat, sites, etc) информации, а в значениях уже массив с данными.
Этот массив передается в следующий метод V:

public function generate($page, $data = null)
{
    if($data) {
        foreach($data as $x => $v) {
            if($x == 'warn') {
                $this->site_warning = $this->get_warning($v);
            }
            if($x == 'data') {
                $this->data = $v;
            }
            if($x == 'task') {
                if($v) {
                    foreach($v as $line) {
                        //...
                    }
                }
            }
            if($x == 'stat') {
                $this->stat = $v;
            }
        }
    }
    include('app/views/' . $page);
}

И в самих вьюшках я уже пишу:

if(isset($this->stat['zones'])) {
    foreach($this->stat['zones'] as $k => $v) {
        echo "<tr>";
        echo "<td>{$k}</td>";
        echo "<td>{$v}</td>";
        echo "</tr>";
    }
}

где $this->stat - свойство класса View, которое заполняется как раз в методе generate, когда ловится ключ 'stat'.

Правильный ли это подход или стоит сделать как-то иначе? Если да, то как именно? Спасибо.

2 ответа 2

2

Это не MVC, а пенитенциарное учреждение с плейсхлодерами. Тут ходи, тут спи, тут ешь, а тут, значит, вали. Не существует правил передачи/впаривания данных между слоями содержания и отображения. Принцип MVC не в организации этих каналов передачи, а в наличии самих слоев. Если они есть - паттерн, если нет - каша. Но вы сосредоточились на каналах.

В слое генерации содержания могут быть любые взаимодействия, любые отношения. Когда содержание готово, оно любым возможным способом передается в отображение. Поскольку отображение знает, что должно прийти, а логика модели создает то, что должно прийти, то прийти может все что угодно в каком угодно виде и формате. В слое отображения никаких взаимодействий между отображениями уже нет, поскольку рендер ведомый, а модель - ведущая, рендер после - модель раньше, ну и все такое.

model test
$this->data = 'Hello Word!';

view test
echo <h1><?php echo $this->data?></h1>

Вот и все.

0

Правильный ли это подход или стоит сделать как-то иначе? Если да, то как именно? Спасибо.

В общем и целом - да, никаких логических ошибок нет.

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

Что мне не нравится (но что вполне допустимо, не всем же приложениям быть жирощеким энтерпрайзом):

  • Стандартизация получения данных и прописывание их конкретному классу. Про непривязанный контекст я уже писал выше, касательно стандартизации - как правило, ни одно приложение не может добиться того, чтобы во всех действиях была идентичная структура данных, даже если она настолько абстрактная. Кроме того, это все собирается из разных мест в одной точке, которую тоже придется редактировать каждый раз при изменениях нижележащих уровней.
  • Шаблон напрямую через include и рендеринг через echo. По-хорошему в шаблон должны вставляться значения, т.е. это как максимум должен быть html-файл с php-вставками, а не наоборот. Когда include делается прямо в контроллере - получается, что контроллер занимается проблемами вьюхи и берет на себя часть работы (как минимум, по поиску шаблона). В идеале прикрутить Twig - это может быть сложным на данном этапе, но лучше этой штуки шаблонизатора для PHP нет.
  • А всё, больше не нашел к чему придраться.

Ваш ответ

By clicking “Отправить ответ”, you agree to our terms of service and acknowledge you have read our privacy policy.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками или задайте свой вопрос.