Przekazywanie danych z kontrolera MVC do podglądu w PHP

Mam własny, ręcznie rozwijany framework PHP MVC dla niektórych projektów, nad którymi pracuję. Kiedy po raz pierwszy stworzyłem framework, było to w kontekście budowania admin CMS. Dlatego też istniała bardzo miła relacja jeden do jednego między modelem, widokiem i kontrolerem. Masz jeden wiersz w DB, który mapuje do jednego modelu. Kontroler ładuje model i przekazuje go do widoku, który ma być renderowany(np. do formularza edycji). Ładnie, czysto i łatwo.

Jednak teraz, gdy pracuję z przodu strony wszystko się klei. Strona nie zawsze jest widokiem pojedynczego modelu. Może to być Lista katalogów użytkowników z 20 użytkownikami (każdy model użytkownika). Ponadto mogą istnieć metadane dotyczące żądania, takie jak paginacja (bieżąca strona, całkowita liczba stron, liczba wyników) i/lub zapytanie wyszukiwania.

Moje pytanie brzmi, jaki jest najczystszy sposób, aby przekazać wszystkie te dane do widoku?

Niektóre opcje rozważam:

  • Mieć kontroler Utwórz tablicę i przekaż ją do widoku jako pojedynczy parametr:

    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
        }
    }
    
  • Utwórz właściwości w klasie view i niech kontroler je wypełni:

    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();
        }
    }
    
  • Daj widok jakiś rodzaj ogólnego obiektu HashMap lub kolekcji jako kontener, który może pomieścić dowolną liczbę i nazwę danych.

    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();
        }
    }
    

Wiem, że technicznie każdy z może działać, ale nie jestem pewien najlepszego wyboru, lub jeśli brakuje mi lepszego lub bardziej konwencjonalnego wyboru.

Author: Brian Tompsett - 汤莱恩, 2009-06-04

3 answers

Polecę koncepcję Fat Models, Chudy Controllers (lub Fat Models Thin Controllers jeśli wolisz...)

Innymi słowy, twój model jest zbyt surowy - Wiązanie Twojego modelu, aby reprezentować tylko coś takiego jak RowDataGateway jest niezwykle ograniczające.

W zasadzie myślę, że dobre modele ukrywają fakt, że w ogóle czytasz dane z bazy danych. Ponieważ w rzeczywistości, Twoje dane mogą być w plikach tekstowych, lub z usługi internetowej, lub cokolwiek innego. Jeśli traktuj swój Model jak tylko gloryfikowany DBAL, skazujesz się na posiadanie ściśle powiązanego kodu w kontrolerach, który po prostu nie pozwoli Ci oderwać się od sposobu myślenia "dane pochodzą tylko z bazy danych".

 3
Author: Peter Bailey,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-04 05:43:23

Widziałem dwie pierwsze metody zaimplementowane w popularnych frameworkach MVC / templating.

Django używa pierwszej metody, przekazując do widoku słownik zmiennych, których widok używa do wypełnienia szablonu.

Smarty używa drugiej metody, tworząc obiekt Smarty i przypisując wartości do każdej właściwości w kontenerze.

Twoja trzecia metoda wydaje się być zasadniczo taka sama jak druga, z małą architekturą różnice.

Naprawdę, chyba nie powiedziałem nic, o czym nie pomyślałeś. Zasadniczo są to wszystkie pomysły na dźwięki, więc wdrażaj to, co czujesz, że czujesz się najbardziej komfortowo.

 0
Author: Marquis Wang,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-04 05:38:47

W tym, którego używam, automatycznie posiada właściwość view w kontrolerze, która umożliwia dostęp do metod i właściwości w widoku. Wszystkie właściwości publiczne są wtedy dostępne w widoku widoku '$ this' , ponieważ widok jest renderowany w kontekście własnych obiektów.

W kontrolerze:

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

I w widoku:

$this->myVar; // 'test'

To samo dotyczy układu, ponieważ oba są oddzielnymi instancjami tego samego obiektu widoku:

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

A potem w układ:

$this->myVar; // 'test'

Framework był kiedyś zastrzeżony, ale wkrótce zostanie udostępniony opinii publicznej. Z chęcią wyślę Ci kod, jeśli uważasz, że to pomoże. Pamiętaj, najprostsza odpowiedź jest zwykle najlepszą odpowiedzią.

 0
Author: Tres,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-06-04 06:53:07