Передача данных из контроллера MVC для просмотра в PHP - PullRequest
15 голосов
/ 04 июня 2009

У меня есть свой собственный PHP MVC-фреймворк для некоторых проектов, над которыми я работаю. Когда я впервые создал фреймворк, это было в контексте построения административной CMS. Следовательно, между моделью, представлением и контроллером были очень хорошие отношения один-к-одному. У вас есть одна строка в БД, которая соответствует одной модели. Контроллер загружает модель и передает ее представлению, которое будет отображено (например, в форму редактирования). Красиво, чисто и просто.

Однако, теперь, когда я работаю над внешним интерфейсом сайта, дела идут не так, как надо. Страница не всегда является представлением одной модели. Это может быть список пользовательских каталогов с 20 пользователями (каждый из которых является моделью пользователя). Кроме того, могут существовать метаданные о запросе, такие как нумерация страниц (текущая страница, общее количество страниц, количество результатов) и / или поисковый запрос.

У меня вопрос: какой самый чистый способ передать все эти данные в представление?

Некоторые варианты, которые я рассматриваю:

  • Пусть контроллер создаст массив и передаст его представлению в виде одного параметра:

    class UserController{
    
        public function renderView(){
    
            // assume there's some logic to create models, get pagination, etc.
            $data = array()
            $data['models'] = $models; 
            $data['currentPage'] = $current;
            $data['totalPages'] = $total;
            return $view->render($data);
        }
    }
    
    class UserView{
        public function render($data){
            // render the data
        }
    }
    
  • Создание свойств в классе представления и заполнение их контроллером:

    class UserView{
        public $models;
        public $currentPage;
        public $totalPages;
    }
    
    class UserController{
    
        public function renderView(){
    
            // assume there's some logic to create models, get pagination, etc.
            $view = new UserView();
            $view->models = $models; 
            $view->currentPage = $current;
            $view->totalPages = $total;
            return $view->render();
        }
    }
    
  • Дайте представлению некоторый вид универсального объекта HashMap или Collection в качестве контейнера, который может содержать любое произвольное число и имя данных.

    class UserView{
        public $collection = new Collection(); // works like a Java collection
    }
    
    class UserController{
    
        public function renderView(){
    
            // assume there's some logic to create models, get pagination, etc. 
            $view = new UserView();
            $view->collection->add($models,'models');
            $view->collection->add($currentPage,'currentPage');        
            return $view->render();
        }
    }
    

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

Ответы [ 3 ]

3 голосов
/ 04 июня 2009

Я собираюсь порекомендовать концепцию Жирные модели, Тощие контроллеры (или, Жирные модели тонких контроллеров , если вы предпочитаете ...)

Другими словами, ваша модель слишком строгая - привязка вашей модели для представления только чего-то вроде RowDataGateway чрезвычайно ограничивает.

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

0 голосов
/ 04 июня 2009

В том, который я использую, он автоматически имеет свойство представления в контроллере, которое позволяет обращаться к методам и свойствам представления. Все общедоступные свойства становятся доступны в представлении представления $ this, поскольку представление отображается в контексте своих объектов.

В контроллере:

$this->view->myVar = 'test';

А в виде:

$this->myVar; // 'test'

То же самое относится и к макету, поскольку оба являются отдельными экземплярами одного и того же объекта вида:

$this->layout->myVar = 'test';

А потом в макете:

$this->myVar; // 'test'

Фреймворк раньше был проприетарным, но скоро будет доступен широкой публике. Я был бы рад выслать вам некоторый код, если вы думаете, что это поможет. Помните, что самый простой ответ - обычно лучший ответ.

0 голосов
/ 04 июня 2009

Я видел оба первых метода, реализованных в популярных MVC / шаблонных средах.

django использует первый метод, передавая представлению словарь переменных, который представление использует для заполнения шаблона.

smarty использует второй метод, создавая объект Smarty и присваивая значения каждому из свойств в контейнере.

Ваш третий метод, по сути, такой же, как и второй, с небольшими архитектурными отличиями.

На самом деле, я полагаю, я не сказал ничего такого, о чем вы еще не подумали. По сути, это все идеи звука, поэтому реализуйте то, что вам наиболее удобно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...