Skocz do zawartości

[PHP] MVC - czarna magia


Markuz

Rekomendowane odpowiedzi

Witam, ostatnio zacząłem się "douczać" php. Już nieco rozumie klasy,obiekty,konstruktory,destruktory i rzeczy tego typu. Teraz chciałbym napisać pierwszy projekt z wykorzystaniem MVC, ale nie mam pojęcia jak zacząć, wiem że w MVC są 3 "rzeczy" - model,widok i kontroler . Wiem o co chodzi z widokiem heh, ale nie wiem za bardzo czym się rożni model od kontrolera. Jakby ktoś miał czas, podpiąć pod ten skrypt (patrz niżej) jakiś prosty model MVC byłbym wdzięczny ( bardzo ) :)

<?php
//Załączone pliki
    require_once('inc/fun.php'); //Funkcje bazy danych
    require_once('inc/theme.php'); //Wygląd
    
//Klasy
    $sql = new Sql;
    $theme = new Theme;
    
//Ustawienia naglowka
    $theme->SetTitle("Strona główna");;
    $theme->ShowHeader();
    
//Zawartosc pliku
    //Panel ostatnio dodane artykuły
        echo "Ostatnio dodane artykuły<br/>";
        $sql->SetQuery("SELECT * FROM art ORDER BY id ASC LIMIT 5");
        while($row = $sql->fetch_assoc()) {
            echo "<img src='http://www.gemzies.com/images/new_search/icon-documents.png'/><a href='#'><b>".$row['nazwa']."</b></a>";
            echo "<br/>";
        }
        
//Stopka pliku
    //Ilosć zapytań sql
        echo "<br/>Zapytań sql: ".$sql->queries;
    
//Koniec pliku
?>

Odnośnik do komentarza
Udostępnij na innych stronach

  • Administratorzy

Z tego co kojarzę, to kontroler pobiera dane z modelu i wyświetla za pomocą widoku.

Służy to temu, że różne kontrolery mogą potrzebować te same dane z modelu (np. lista użytkowników), a po co obrabiać je w dwóch różnych miejscach pisząc ten sam kod, jak można raz napisać klasę i metodę i potem tylko wywoływać. Widok z kolei te pobrane dane z modelu odpowiednio wyświetla.

 

Ot tak najprościej mozna to powiedziec, nie wiem tylko czy się gdzieś w tym uproszczaniu nie zakręciłem.

Odnośnik do komentarza
Udostępnij na innych stronach

  • Filar Społeczności

Jak piszesz, że znalazłeś prosty framework MVC, to warto by było podać jego nazwę.

 

Co zaś tyczy się samej idei MVC, to gnysek troszkę źle wytłumaczył. Mianowicie kontroler wcale nie musi pobierać danych z modelu i wyświetlać za pomocą widoku, ponieważ we wzorcowym frameworku mvc powinna być możliwość bezpośredniej interakcji między modelem a widokiem, bez potrzeby używania kontrolera. Dlaczego? Ponieważ:

M - Model jest przedstawieniem danych w pewnej postaci (dlatego nazywa się modelem)

V - Widok to sposób wyświetlania danych

C - Kontroler przetwarza dane wejściowe, odpowiada za logikę

 

Jeżeli widok ma zaprezentować proste dane z modela, których nie trzeba specjalnie przetwarzać i obrabiać, to kontroler nie powinien stawać pomiędzy widokiem a modelem, bo nie musi.

Odnośnik do komentarza
Udostępnij na innych stronach

W praktyce w stronach/aplikacjach internetowych wygląda to mniej więcej tak:

Model zawiera klasy, które wykonują operacje na bazie danych (pobiera, dodaje, usuwa, zmienia).

Widok wyświetla "widoki" np. stronę główną, artykuł itp. Korzysta przy okazji z systemu szablonów.

Kontroler pobiera żądania od użytkownika i nakazuje Widokowi wyświetlenie określonego "widoku", przekazuje mu też dane pobrane z Modelu.

 

W czystym MVC Widok powinien być na bieżąco informowany przez Model o zaistnieniu jakiejś zmiany, jednak tak jak Ranmus napisał, Widok może się komunikować z Modelem. Nazywa się to chyba MVC model 2 czy jakoś tak.

Odnośnik do komentarza
Udostępnij na innych stronach

Sorry, że odpowiadam co napisali już Gnysek i Ranmus, ale zacząłem to pisać 2h temu (byłem w między czasie na rowerze), no więc:

 

W modelu o to chodzi, aby opakować w nim wszelkie dane z źródeł tj. bazy danych, pliki itd.

Kontroler praktycznie powinien tylko pobierać dane z modelu, robić na nich obróbkę, wszelkie działania i ewentualnie przekazywać go do widoku. Jest tak, że ilu programistów to jest tyle implementacji MVC :)

Drobny przykład poniżej.

 

system/controllerbase.php

<?php
abstract class ControllerBase
{
    /**
     * Wskaźnik do View'a
     * @var View
     */
    public $view = null;
    
    /**
     * Przełącznik automatycznego renderowania
     * @var bool
     */
    public $automaticRender = true;
    
    /**
     * Konstruktor
     * @param $view View 
     */
    public function __construct( &$view )
    {
        $this->view = $view;
    }
    
    /**
     * Uruchamianie akcji (metody) ... nie powinneneś się zagłębiać w to jak to działa, piszę to jedynie w celu pomocniczym
     * @param $action string Nazwa akcji
     * @param $parameters array Parametry, przekazuje to np. router
     */
    public function __execute( $action, $parameters )
    {
        call_user_func_array( array( $this, $action ), $parameters );
    }
    
    /**
     * Jakiś bajer, np. obsługa 404
     * @param $action string Nazwa akcji
     */
    abstract function on404( $action );
}
?>

 

system/view.php

<?php
class View
{
    private $data = array();
    
    /**
     * Ustawianie zmiennych
     * @param $k string klucz
     * @param $v mixed wartość
     */
    public function __set( $k, $v )
    {
        $this->data[ $k ] = $v;
    }
    
    /**
     * Wyświetla templatke z naszymi ustawionymi zmiennymi
     * @param $filename string ścieżka do pliku tpl
     * @param $output bool wyświetlać?
     * @return string no, "zrenderowany" szablon :)
     */
    public function render( $filename, $output = FALSE )
    {
        foreach( $this->data as $k => $v )
        {
            ${$k} = $v;
        }
        
        ob_start();
        include $filename;
        $r = ob_get_content();
        ob_end_flush();
        
        if( $output ) echo $r;
        
        return $r;
    }
}
?>

 

system/router.php

<?php 
class Router
{
    /**
     * Przykład uruchamiania kontrolera
     */
    public static function run()
    {
        $lol = array_values( $_GET );
        $controller    = array_shift( $lol );
        $action        = array_shift( $lol );
        
        if( !$controller )     $controller = 'index';
        if( !$action )        $action = 'index';
        
        if( !file_exists( 'controllers/' . $controller . '.php'  ) )
        {
            throw new Exception();
        }
        
        $s = $controller . 'Controller';
        $oController = new $s( new View );
        $oController->__execute( $action, $lol );
        
        if( $oController->automaticRender )
            $oController->view->render( 'views/' . $controller . '/' . $action . '.php', TRUE );
            
        //blah coś tam dalej może być owszem
    }
}
?>

 

controllers/index.php

<?php
/*
TO JEST KURWA jakiś sobie przykładowy kontroler;)
*/
class indexController
{
    public function index()
    {
        $model = new Model( 40 );
        $this->view->blah = $model->getContent();
    }
    
    public function lol( $nick )
    {
        $this->automaticRender = false;
        echo 'Siema <strong>' . $nick . '</strong>';
    }
}
?>

 

models/model.php (ładowanie modeli itd. musisz sam sobie rozkminić)

<?php
class Model
{
    private $content;
    
    public function __construct( $id )
    {
        $this->content = file_get_contents( 'data/ ' . $id . '.txt' );
    }
    
    public function getContent()
    {
        return $this->content;
    }
}
?>

 

index.php

<?php
$dirs = array( 'system', 'controllers', 'models' ); //a jednak Ci zrobię to ładowanie modeli xD

foreach( $dirs as $dir )
{
    foreach( glob( $dir . '/*.php' as $file )
    {
        require $dir . '/' . $file;
    }
}

Router::run();
?>

 

Jest to kod pisany bez żadnej dokumentacji, bez sprawdzania składni chociażby :D funkcje mogą się różnić, ale mam nadzieje, że metodologia działania jest taka jaka powinna być... w prawdzie zrobiłem Ci tu zalążek frameworka MVC, ale co to zmienia :)

Ranmus narzekał, że nigdy swojej wypowiedzi nie argumentuje, to mam nadzieję, że tym nadrobię.

Zanim się poleje fala krytyki, proszę zauważyć, że jest tyle implementacji MVC ilu jest programistów :)

 

Nie chcę, abyś to kopiował na żywca, w miare możliwości to przeanalizuj, podpatrz jak to działa i napisz własną implementacje.

 

POZDRO POĆWICZ.

Odnośnik do komentarza
Udostępnij na innych stronach

Panowie ładnie wszystko sprzedali, ja tylko dam tipa dla Kofelka odnośnie tego:

        foreach( $this->data as $k => $v )
        {
            ${$k} = $v;
        }

http://php.net/manual/pl/function.extract.php

 

Swoją drogą, to co napisał Kofel bardzo przypomina mi starszą Kohanę. :)

Odnośnik do komentarza
Udostępnij na innych stronach

Jeśli chcesz dodać odpowiedź, zaloguj się lub zarejestruj nowe konto

Jedynie zarejestrowani użytkownicy mogą komentować zawartość tej strony.

Zarejestruj nowe konto

Załóż nowe konto. To bardzo proste!

Zarejestruj się

Zaloguj się

Posiadasz już konto? Zaloguj się poniżej.

Zaloguj się
  • Ostatnio przeglądający   0 użytkowników

    • Brak zarejestrowanych użytkowników przeglądających tę stronę.
×
×
  • Dodaj nową pozycję...