首页 文章

将数据从MVC Controller传递到PHP中的View

提问于
浏览
15

对于我正在研究的一些项目,我有自己的手动PHP MVC框架 . 当我第一次创建框架时,它是在构建管理CMS的上下文中 . 因此,模型,视图和控制器之间存在非常好的一对一关系 . 数据库中有一行,它映射到单个模型 . 控制器加载模型并将其传递给要渲染的视图(例如进入编辑表单) . 很好,干净,容易 .

但是,现在我正在网站的前端工作,事情变得棘手了 . 页面并不总是单个模型的视图 . 它可能是一个包含20个用户的用户目录(每个用户模型) . 此外,可能存在关于请求的元数据,例如分页(当前页面,总页数,结果数量)和/或搜索查询 .

我的问题是,将所有这些数据传递给视图的最简洁方法是什么?

我正在考虑的一些选择:

  • Have the controller create an array and pass that to the view as a single parameter:
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
    }
}
  • Create properties in the view class and have the controller populate them:
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();
    }
}
  • Give the view some sort of generic HashMap or Collection object as a container which can hold any arbitrary number and name of data.
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 回答

  • 0

    我打算推荐Fat Models, Skinny Controllers的概念(或者,如果你愿意的话,Fat Models Thin Controllers ......)

    换句话说,你的模型太严格了 - 将你的模型绑定到只表示像RowDataGateway这样的东西是非常有限的 .

    事实上,我认为好的模型隐藏了你从数据库中读取数据的事实 . 实际上,因为您的数据可能位于文本文件中,也可能来自Web服务或其他任何内容 . 如果你认为你的模型只不过是一个美化的DBAL,你就会在控制器中使用紧密耦合的代码,这样你就不会让你脱离“数据来自数据库”的思维方式 .

  • 0

    我已经看到了流行的MVC /模板框架中实现的前两种方法 .

    django使用第一种方法,将视图用于填充模板的变量字典传递给视图 .

    smarty使用第二种方法,创建Smarty对象并为容器中的每个属性分配值 .

    您的第三种方法似乎与第二种方法基本相同,但架构方面存在细微差别 .

    真的,我想我还没有说过你没想过的任何事情 . 基本上,这些都是听起来的想法,所以要实现你觉得最舒服的任何东西 .

  • 3

    在我使用的那个中,它在控制器中自动拥有一个view属性,您可以访问视图上的方法和属性 . 然后可以在视图视图'$ this'中访问所有公共属性,因为视图在其自己的对象上下文中呈现 .

    在控制器中:

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

    在视图中:

    $this->myVar; // 'test'
    

    布局也是如此,因为它们都是同一视图对象的独立实例:

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

    然后在布局中:

    $this->myVar; // 'test'
    

    该框架曾经是专有的,但即将向公众发布 . 如果您认为有帮助,我很乐意向您发送一些代码 . 请记住,最简单的答案通常是最好的答案 .

相关问题