Как правильно передавать данные с контроллера для просмотра?

Моя текущая реализация:

class SomeController extends AppController { function someaction() { $d['text'] = "ahoy!"; $this->render("someactionView", $d); } } 

И в AppController :

 function render($file, $data = "") { require "views/" . $file . ".php"; } 

И $data будут доступны в файле представлений. Это правильная реализация? Существуют ли какие-либо ошибки с этой реализацией?

И $data будут доступны в файле представлений. Это правильная реализация? Существуют ли какие-либо ошибки с этой реализацией?

В основном вы реализуете его, как это делают большинство фреймворков. Есть пара проблем с этим:

  • Контроллер принимает вход и отправляет вывод (который нарушает принцип единой ответственности)
  • Вид тесно связан с HTML. Из-за этого вы не можете повторно использовать один и тот же вид для другого материала, например XML, JSON.
  • Если вам require "views/" . $file . ".php"; require "views/" . $file . ".php"; в методе render() – вы снова смешаете его. Что делать, если вы меняете местоположение просмотров? Тогда вам придется немного переписать свой метод. Этот подход просто убивает способность повторного использования.

Чтобы обновить свои базовые знания:

Контроллер (также известный как редактор)

Служит исключительно для особых целей. Он изменяет состояние модели – то есть он должен принимать входные данные, полученные от $_POST , $_GET , $_FILES , $_COOKIE . В контроллере должно выполняться только назначение переменных и не более того .

 class Controller { public function indexAction() { $this->view->setVar('age', $this->request->getPostParam('age')); $this->view->setVar('user', $this->request->getPostParam('user')); //... } } 

Посмотреть

Вид имеет прямой доступ к модели. Чтобы сделать просмотр более доступным и удобным для вас, вам лучше передать требуемые вещи в качестве функциональных параметров (или через сеттеры)

 class View { public function render($templateFile, array $vars = array()) { ob_start(); extract($vars); require($templateFile); return ob_get_clean(); } } 

Как инициализировать представление и как переменные должны быть переданы ему?

Прежде всего – представление должно быть создано за пределами MVC-триады. Поскольку контроллер записывает либо для просмотра, либо для модели – вы должны передавать переменные для просмотра через контроллер.

 $model = new Model(); $view = new View($model); $controller = new Controller($view); // This will assign variables to view $controller->indexAction(); echo $view->render(); 

Примечание. В сценарии реального мира модель не является классом, а слоем абстракции. Я называю это Model для демонстрационных целей.

IMO метод render() относится к представлению, а не к контроллеру. Код должен выглядеть так:

контроллер:

 class SomeController extends AppController { function someaction() { $d['text'] = "ahoy!"; $view = new SomeActionView(); $view->assign('data', $d); echo $view->render(); } } 

Просмотреть базовый класс:

 class View { protected $data; function render($template) { ob_start(); // you can access $this->data in template require "views/" . $template . ".php"; $str = ob_get_contents(); ob_end_clean(); return $str; } function assign($key, $val) { $this->data[$key] = $val; } } 

Расширить класс просмотра

 class SomeActionView extends View { public function render($template = 'someActionTemplate') { return parent::render($template); } } 

Это правильная реализация? Существуют ли какие-либо ошибки с этой реализацией?

Короткий ответ: нет и несколько.

Прежде всего, то, что у вас там, отсутствует. Это просто немой шаблон php . Представления в MVC являются экземплярами, которые содержат логику пользовательского интерфейса для приложения. Они извлекают информацию из уровня модели и, основываясь на полученной ими информации, создают ответ. Этот ответ может быть простым текстом, JSON-документом, HTML-страницей, собранной из нескольких шаблонов или просто HTTP-заголовком.

Что касается контроллера, то только задача – изменить состояние уровня модели и (в редких случаях) текущего вида. Контроллеры не инициализируют представления и не заполняют шаблоны.