2009-06-04 134 views
15

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

但是,现在我正在网站的前端工作,事情变得粘滞。一个页面并不总是一个模型的视图。它可能是一个用户目录,包含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

我要推荐的Fat Models, Skinny Controllers概念(或者,Fat Models Thin Controllers如果你喜欢...)

。换句话说,你的模型过于严格 - 绑你的模型来表示只像一个RowDataGateway极其限制。

事实上,我认为好的模型隐藏了你从数据库中读取数据的事实。因为,实际上,您的数据可能在文本文件中,或来自Web服务或其他任何内容。如果你只将你的模型看作是荣耀的DBAL,那么你就会注意到在你的控制器中有紧密耦合的代码,它们不会让你摆脱“数据只来自数据库”的思维方式。

+1

有趣的是,在我发布这个问题之前,我刚刚阅读了Jamis Buck关于胖模型的文章,但我没有意识到使用Google搜索这个概念会在这个概念上返回如此丰富的资源。我认为这只是他自己的小哲学。谢谢你的提示。 – 2009-06-04 06:06:42

+0

好文章:-)我不确定我完全同意胖模式的想法。我认为这个模型应该只是一个模型,其方法本身就是行为(单数)。换句话说,像FindPeople()这样的方法不适合。然而,我完全同意瘦身控制器的好处。输入服务层的参数。现在我对此不甚了解,不会声称是专家,但我认为它值得指出。 是的,它会增加新层的额外复杂度,但控制器可以调用例如PeopleService :: FindPeople() – 2009-06-04 08:20:58

0

我见过在流行的MVC /模板框架中实现的前两种方法。

django使用第一种方法,向视图传递视图用来填充模板的变量字典。

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

你的第三种方法似乎基本上与第二种方法相同,只是体系结构有微小差异。

真的,我想我没有说过任何你没有想到的事情。基本上,这些都是听起来的想法,所以实施任何你觉得你最舒服的。

0

在我使用的一个中,它在控制器中自动具有视图属性,您可以访问视图上的方法和属性。所有公共属性都可以在视图'$ this'内访问,因为视图是在它自己的对象上下文中呈现的。

在控制器:

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

并在视图:

$this->myVar; // 'test' 

这同样适用于布局,因为是相同的视图对象的两个不同实例:

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

然后在布局中:

$this->myVar; // 'test' 

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

相关问题