2009-06-04 196 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' 

該框架曾經是專有的,但即將發佈給公衆。如果您認爲有幫助,我很樂意向您發送一些代碼。請記住,最簡單的答案通常是最好的答案。

相關問題