it-swarm.com.de

Ein Beispiel für eine MVC-Steuerung

Ich habe viel darüber gelesen, wie und warum ein MVC-Ansatz in einer Anwendung verwendet wird. Ich habe Beispiele eines Modells gesehen und verstanden, ich habe Beispiele der Ansicht gesehen und verstanden ..., aber ich bin immer noch ein bisschen verschwommen auf dem Controller. Ich würde wirklich gerne ein gründlich genug Beispiel eines Controllers sehen. (in PHP wenn möglich, aber jede Sprache wird helfen)

Vielen Dank.

PS: Es wäre auch toll, wenn ich ein Beispiel für eine index.php-Seite sehen könnte, die entscheidet, welcher Controller verwendet wird und wie.

BEARBEITEN: Ich weiß, was die Aufgabe des Controllers ist, ich verstehe nicht wirklich, wie ich das in OOP erreichen kann.

38
BDuelz

Anforderungsbeispiel

Fügen Sie so etwas in Ihren index.php ein:

<?php

// Holds data like $baseUrl etc.
include 'config.php';

$requestUrl = 'http://'.$_SERVER['HTTP_Host'].$_SERVER['REQUEST_URI'];
$requestString = substr($requestUrl, strlen($baseUrl));

$urlParams = explode('/', $requestString);

// TODO: Consider security (see comments)
$controllerName = ucfirst(array_shift($urlParams)).'Controller';
$actionName = strtolower(array_shift($urlParams)).'Action';

// Here you should probably gather the rest as params

// Call the action
$controller = new $controllerName;
$controller->$actionName();

Wirklich einfach, aber Sie haben die Idee ... (Ich habe mich auch nicht um das Laden der Controller-Klasse gekümmert, aber ich denke, das kann entweder über das automatische Laden erfolgen oder Sie wissen, wie es geht.)

Einfaches Controller-Beispiel (Controller/login.php):

<?php    

class LoginController
{
    function loginAction()
    {
        $username = $this->request->get('username');
        $password = $this->request->get('password');

        $this->loadModel('users');
        if ($this->users->validate($username, $password))
        {
            $userData = $this->users->fetch($username);
            AuthStorage::save($username, $userData);
            $this->redirect('secret_area');
        }
        else
        {
            $this->view->message = 'Invalid login';
            $this->view->render('error');
        }
    }

    function logoutAction()
    {
        if (AuthStorage::logged())
        {
            AuthStorage::remove();
            $this->redirect('index');
        }
        else
        {
            $this->view->message = 'You are not logged in.';
            $this->view->render('error');
        }
    }
}

Wie Sie sehen, kümmert sich der Controller um den "Fluss" der Anwendung - die sogenannte Anwendungslogik. Es kümmert sich nicht um die Speicherung und Präsentation von Daten. Es sammelt vielmehr alle erforderlichen Daten (abhängig von der aktuellen Anfrage) und ordnet sie der Ansicht zu ...

Beachten Sie, dass dies mit keinem mir bekannten Framework funktionieren würde, aber ich bin mir sicher, dass Sie wissen, was die Funktionen tun sollen.

60
Franz

Stellen Sie sich vor, es gibt Bildschirme in einer Benutzeroberfläche, einen Bildschirm, in den ein Benutzer einige Suchkriterien eingibt, einen Bildschirm, in dem eine Liste von Zusammenfassungen übereinstimmender Datensätze angezeigt wird, und ein Bildschirm, auf dem ein Datensatz ausgewählt wird, nachdem er zur Bearbeitung ausgewählt wurde. Es wird einige Logik bezüglich der anfänglichen Suche in den Zeilen von geben

if search criteria are matched by no records
    redisplay criteria screen, with message saying "none found"
else if search criteria are matched by exactly one record
    display edit screen with chosen record
else (we have lots of records)
    display list screen with matching records

Wohin soll diese Logik gehen? Nicht in der Ansicht oder Modell sicher? Daher ist dies die Aufgabe des Controllers. Der Controller wäre auch dafür verantwortlich, die Kriterien zu übernehmen und die Model-Methode für die Suche aufzurufen.

1
djna
<?php

class App {
    protected static $router;

    public static function getRouter() {
        return self::$router;
    }

    public static function run($uri) {
        self::$router = new Router($uri);

        //get controller class
        $controller_class = ucfirst(self::$router->getController()) . 'Controller';
        //get method
        $controller_method = strtolower((self::$router->getMethodPrefix() != "" ? self::$router->getMethodPrefix() . '_' : '') . self::$router->getAction());

        if(method_exists($controller_class, $controller_method)){
            $controller_obj = new $controller_class();
            $view_path = $controller_obj->$controller_method();

            $view_obj = new View($controller_obj->getData(), $view_path);
            $content = $view_obj->render();
        }else{
            throw new Exception("Called method does not exists!");
        }

        //layout
        $route_path = self::getRouter()->getRoute();
        $layout = ROOT . '/views/layout/' . $route_path . '.phtml';
        $layout_view_obj = new View(compact('content'), $layout);
        echo $layout_view_obj->render();
    }

    public static function redirect($uri){
        print("<script>window.location.href='{$uri}'</script>");
        exit();
    }
}
0
David
<?php
class Router {

    protected $uri;

    protected $controller;

    protected $action;

    protected $params;

    protected $route;

    protected $method_prefix;

    /**
     * 
     * @return mixed
     */
    function getUri() {
        return $this->uri;
    }

    /**
     * 
     * @return mixed
     */
    function getController() {
        return $this->controller;
    }

    /**
     * 
     * @return mixed
     */
    function getAction() {
        return $this->action;
    }

    /**
     * 
     * @return mixed
     */
    function getParams() {
        return $this->params;
    }

    function getRoute() {
        return $this->route;
    }

    function getMethodPrefix() {
        return $this->method_prefix;
    }

        public function __construct($uri) {
            $this->uri = urldecode(trim($uri, "/"));
            //defaults
            $routes = Config::get("routes");
            $this->route = Config::get("default_route");
            $this->controller = Config::get("default_controller");
            $this->action = Config::get("default_action");
            $this->method_prefix= isset($routes[$this->route]) ? $routes[$this->route] : '';


            //get uri params
            $uri_parts = explode("?", $this->uri);
            $path = $uri_parts[0];
            $path_parts = explode("/", $path);

            if(count($path_parts)){
                //get route
                if(in_array(strtolower(current($path_parts)), array_keys($routes))){
                    $this->route = strtolower(current($path_parts));
                    $this->method_prefix = isset($routes[$this->route]) ? $routes[$this->route] : '';
                    array_shift($path_parts);
                }

                //get controller
                if(current($path_parts)){
                    $this->controller = strtolower(current($path_parts));
                    array_shift($path_parts);
                }

                //get action
                if(current($path_parts)){
                    $this->action = strtolower(current($path_parts));
                    array_shift($path_parts);
                }

                //reset is for parameters
                //$this->params = $path_parts;
                //processing params from url to array
                $aParams = array();
                if(current($path_parts)){ 
                    for($i=0; $i<count($path_parts); $i++){
                        $aParams[$path_parts[$i]] = isset($path_parts[$i+1]) ? $path_parts[$i+1] : null;
                        $i++;
                    }
                }

                $this->params = (object)$aParams;
            }

    }
}
0
David
  1. Ordnerstruktur erstellen
  2. Richten Sie .htaccess & virtuelle Hosts ein
  3. Konfigurationsklasse erstellen, um Konfigurationsarray zu erstellen

Regler

  1. Erstellen Sie eine Routerklasse mit geschütztem, nicht statischem Inhalt mit Gettern
  2. Erstellen Sie die init.php mit config include & autoload und include Pfaden (lib, controlelrs, models)
  3. Konfigurationsdatei mit Routen und Standardwerten erstellen (Route, Controller, Aktion)
  4. Legen Sie Werte in den Router-Standardwerten fest
  5. Legen Sie UI-Pfade fest, explodieren Sie den URI und legen Sie Route, Controller, Aktion, Parameter, Prozessparameter fest.
  6. Erstellen Sie eine App-Klasse, um die Anwendung auszuführen, indem Sie uri - (protected router obj, runc) ausführen.
  7. Erstellen Sie die übergeordnete Controller-Klasse, um alle anderen Controller zu erben (geschützte Daten, Modell, Parameter - nicht statisch) Daten setzen, Parameter im Konstruktor.
  8. Erstellen Sie einen Controller und erweitern Sie ihn mit der übergeordneten Klasse und fügen Sie eine Standardmethode hinzu.
  9. Rufen Sie die Controller-Klasse und -Methode in Run-Funktion auf. Methode muss mit Präfix sein.
  10. Rufen Sie die Methode auf, falls vorhanden

Ansichten

  1. Erstellen Sie eine übergeordnete Ansichtsklasse, um Ansichten zu generieren. (Daten, Pfad) mit Standardpfad, Controller einstellen, Renderfunktionen auf den vollständigen Pfad zurückgeben (nicht statisch)
  2. Erstellen Sie eine Renderfunktion mit ob_start () und ob_get_clean, um den Inhalt zurückzugeben und an den Browser zu senden.
  3. Ändern Sie die App-Klasse, um die Daten zu analysieren, um die Klasse anzuzeigen. Wenn Pfad zurückgegeben wird, übergeben Sie auch die Ansichtsklasse.
  4. Layouts .. Layout ist abhängig vom Router. Analysieren Sie die Layout-HTML-Datei erneut, um sie anzuzeigen und zu rendern 
0
David