Model View Controller (MVC), ein Entwurfsmuster (Pattern)PHP-Framework Lernprogramm #1

Model View Controller

Der englischsprachige Begriff model view controller (MVC, englisch für Modell-Präsentation-Steuerung) ist ein Muster zur Strukturierung von Software-Entwicklung in die drei Einheiten Datenmodell (engl. model), Präsentation (engl. view) und Programmsteuerung (engl. controller). Manche Autoren stufen es als Architekturmuster ein, andere als Entwurfsmuster. Ziel des Musters ist ein flexibler Programmentwurf, der eine spätere Änderung oder Erweiterung erleichtert und eine Wiederverwendbarkeit der einzelnen Komponenten ermöglicht.

Das Entwurfmuster Model View Controller (MVC Prinzip) , ist ein Muster (Pattern) einer strukturierten Entwicklung von Software-Applikationen.
Eine logische Übersicht einzelner Klassen in der Objekt Orientierten Programmierung (OOP) mit PHP ist für ein effizientes Arbeit unerläßlich. Allein die Fehlersuche im unendlichen Code einer Anwendung kann ohne ein enstprechendes Entwurfsmuster schnell frustierend sein.

Ein PHP-Framework nach dem Entwurfmuster Model View Controller (MVC) ist gerade für Einsteiger in die Objekt Orientierte Programmierung (OOP) eine exzellente Alternative, die geschriebenen Dateien eines Softwareprogramm zu organisieren.

Die Struktur ist einfach und klar, die Aufgaben der Klassen der Softwareanwendung exakt definiert. Jede Datei der Applikation wird entsprechend seiner Funktion den einzelnen Bestandteilen des Entwurfmusters zugeordnet.

Model View Controller (MVC) Framework PHP, Tutorial in Deutsch
Model View Controller (MVC), ein Entwurfsmuster (Pattern)
PHP-Framework, das Prinzip · Lernprogramm Teil 1

Model View Controller

Der englischsprachige Begriff model view controller (MVC, englisch für Modell-Präsentation-Steuerung) ist ein Muster zur Strukturierung von Software-Entwicklung in die drei Einheiten Datenmodell (engl. model), Präsentation (engl. view) und Programmsteuerung (engl. controller). Manche Autoren stufen es als Architekturmuster ein, andere als Entwurfsmuster. Ziel des Musters ist ein flexibler Programmentwurf, der eine spätere Änderung oder Erweiterung erleichtert und eine Wiederverwendbarkeit der einzelnen Komponenten ermöglicht.

Model View Controller einfach erklärt

Das Konzept des MVC Pattern ist mit der folgenden Liste erkennbar. Die einzelnen Module einer Softwareprogramm (Applikation), entwickelt mit einem PHP-Framework nach dem hier vorgestellten Entwurfmuster, können klar zugeordnet werden.
Das erleichtert die Fehlerfindung innerhalb der Anwendung oder das Ergänzung von Bestandteilen im Code. Auch die Wiedervewendbarkeit einzelner Bestandteile (Module) des Model View Controller Entwurfmuster ist ebenfalls ein starkes Argument, dieses Pattern für die Software-Entwicklung mit PHP einzusetzen.

  • M model (Model)

    Das Model des MVC Prinzip enthält die darzustellenden Daten, gibt sie auf Anforderung an die Steuerung (Controller). Diese Daten können in einer Datenbank liegen, in einer File oder in einer Variable abgelegt sein.
  • V view (Präsentation)

    Der View des MVC Prinzip ist für die Darstellung der benötigten Daten aus dem Modell (Model) nach den Benutzerinteraktionen zuständig. Sie wird genutzt zur Modelierung für die Ausgabe.
  • C controller (Steuerung)

    Das C im MVC Entwurfsmuster steht für Controlling (Steuerung). Der Controller nimmt die Benutzeraktionen entgegen, wertet diese aus und agiert entsprechend.

Ein PHP-Skript "Hello World" nach dem Entwurfsmuster Model View Controller ( MVC )

Dieses einfache PHP Skript "Hello World" nach dem Entwurfsmuster Model View Controller dient als Grundlage des Lernprogramm PHP-Framework - das Prinzip erklärt an einem "Hello World".
Das Ausgangs-Skript wird entsprechend dem jeweiligen Lernschritt der folgenden Kapitel dieses Tutorial und dessen Lernziel erweitert angepasst.

Nachfolgend werden die einzelnen Bestandteile des PHP-Skript zur Erklärung des MVC Prinzip vorgestellt.

Das gewünschte Ergebnis "Hello World" Model View Controller (MVC)

Das nachfolgende Fenster zeigt die Augabe des Tutorial PHP "Hello World" nach dem Entwurfmuster Model View Controller (MVC).

Die Ausgabe der Anwendung am Bildschirm (Destkop) des Benutzers (Users), also am Frontend

Die Klassen des Lernpgrogramm

!!! WICHTIGER GRUNDSATZ !!! In der Objekt Orientierten Programmiereung (OOP) soll jede Klasse hat genau nur eine Aufgabe haben! Die Regel dieser Richtlinie beim Entwickeln von Softwareanwendungen ist in dem Single-Responsibility-Prinzip (SRP) definiert. Dieses Tutorial wird dieser Empfehlung soweit es geht folgen.

Anmerkung: Zur besseren Zuordnung der einzelnen Klassen unseres Projektes zum Entwurfmuster, werden die Klassenbezeichnungen mit dem jeweiligen Identifikator des Model View Controlling (MVC) etiquiert, also z.Bsp: class ModelNavigation{...}.

Die Model-Klassen Model*

Die Model-Klassen halten den unformatierten Text (String) für die formatierte Ausgabe bereit. Im Tutorial sind das drei Klassen:

  • Klasse class ModelNavigation{...}

    Die Klasse class ModelNavigation enthält ein Array mit den einzelnen Sprachoptionen
    /**
     * Klassenname: ModelNavigation
     * Klassentyp nach MVC: model
     * Methoden (function): RawString()
     * Eigenschaften / Property (Variablen): $arrNavigation (Type: Array)
     *
     * Projekt Aufgabe: stellt den String des sprachspezifischen Link der in der
     * Navigation
     */
    class ModelNavigation {
    	public function RawString() {
    		return $arrNavigation = array (
    				"deutsch" => "Deutsch",
    				"english" => "English",
    				"español" => "Español" 
    		);
    	}
    }
    
    "Hello World" Model View Controller (MVC): class ModelNavigation{}
    + Klasse anzeigen - Klasse verbergen

    Klasse class ModelTitleH1{...}

    Die Klasse class ModelTitleH1 enthält ein Array mit den sprachspezifischen "Hello World" für den HTML-Tag h1
    /**
     * Klassenname: ModelTitleH1
     * Klassentyp nach MVC: model
     * Methoden (function): RawString()
     * Eigenschaften / Property (Variablen): $arrStringHelloWorld (Type: Array)
     *
     * Projekt Aufgabe: stellt die verschiedensprachigen "Hello World" Titel bereit
     */
    class ModelTitleH1 {
    	public function RawString() {
    		return $arrStringHelloWorld = array (
    				"deutsch" => "Hallo Welt",
    				"english" => "Hello World",
    				"español" => "Hola Mundo" 
    		);
    	}
    }
    
    "Hello World" Model View Controller (MVC): class ModelTitleH1{}
    + Klasse anzeigen - Klasse verbergen

    Klasse class ModelFloat{...}

    Die Klasse class ModelNavigation enthält ein Array mit einem Sprachspezifischen Text "Thank you"
    /**
     * Klassenname: ModelFloat
     * Klassentyp nach MVC: model
     * Methoden (function): RawString()
     * Eigenschaften / Property (Variablen): $arrStringThankYou (Type: Array)
     *
     * Projekt Aufgabe: stellt die verschiedensprachigen "Thank You" Strings bereit
     */
    class ModelFloat {
    	public function RawString() {
    		return $arrStringThankYou = array (
    				"english" => "Thank you for use this Tutorial",
    				"deutsch" => "Vielen Dank das Sie unser Lernprogramm benutzen",
    				"español" => "Muchas gracias por utilizar este tutorial" 
    		);
    	}
    }
    
    "Hello World" Model View Controller (MVC): class ModelFloat{}
    + Klasse anzeigen - Klasse verbergen

Die View-Klasse View*

Die View-Klasse ist für die Aufbereitung der unformatierten Text-Bausteine (String) aus den Model-Klassen zu einem formatierten Strings verantwortlich:

  • Klasse class ViewHtmlString{...}

    Die in dieser Klasse enthaltenen Methoden übergeben entsprechend der empfangenden Eigenschaften (Variablen) an den Controller einen HTML konformen String.
    /**
     * Klassenname: ViewHtmlString
     * Klassentyp nach MVC: view
     * Methoden (function):
     * - GeneratedHtmlString()
     * - get_class() -> http://php.net/manual/de/function.get-class.php
     * Eigenschaften / Property (Variablen):
     * - $viewOutput (Type: $tring)
     * - $arrObjModel (Type: Array)
     * - $lang (Type: String)
     * - $_SERVER['PHP_SELF'] ->
     * http://php.net/manual/de/reserved.variables.server.php
     *
     * Projekt Aufgabe: unformatierten String in HTML konformen String wandeln und
     * diesen zurückgeben
     */
    class ViewHtmlString {
    	protected $viewOutput;
    	public function GeneratedHtmlString($arrObjModel, $desiredLanguage) {
    		/**
    		 * Schleife durchläuft das vom Controller übergebene Array $arrObjModel.
    		 * Array $arrObjModel enthält die im Controller initialisierten Objekte
    		 * der Modelklassen
    		 */
    		foreach ( $arrObjModel as $for ) {
    			/**
    			 * in $retFromMethode wird die Rückgabe des jeweiligen Model-Objekt
    			 * gespeichert
    			 */
    			$retFromMethode = $for->RawString ();
    			/**
    			 * mit get_class() wird der Klassenname des jeweiligen Model-Objekt
    			 * ermittelt, jeder String aus den jeweiligen Objekten bekommt im
    			 * case() seinen individuellen HTML-Tag zugeordnet
    			 */
    			switch (get_class ( 
    				$for )) {
    				/**
    				 * die Rückgabe des Objektes der class ModelNavigation{} wird
    				 * mit einem foreach() durchlaufen und jedes Element wird in ein
    				 * a-Tag eingebunden und dem String $this->viewOutput
    				 * angehangen
    				 */
    				case ("ModelNavigation") :
    					foreach ( array_keys ( 
    						$retFromMethode ) as $key ) {
    						$this->viewOutput .= "<a href=\"{$_SERVER['PHP_SELF']}?{$key}\">" .
    							 $retFromMethode [$key] .
    							 '</a> ';
    					}
    					break;
    				/**
    				 * der String aus dem Array der Rückgabe vom Objekt der class
    				 * ModelTitleH1{} wird anhand des Schlüssel (key) $lang
    				 * gefiltert.
    				 * Dieser String wird in ein h1-Tag eingebunden und dem String
    				 * $this->viewOutput angehangen
    				 */
    				case ("ModelTitleH1") :
    					$this->viewOutput .= '<h1>' .
    						 $retFromMethode [$desiredLanguage] .
    						 '</h1>';
    					break;
    				/**
    				 * der String aus dem Array der Rückgabe vom Objekt der class
    				 * ModelFloat{} wird anhand des Schlüssel (key) $lang gefiltert.
    				 * Dieser String wird in ein p-Tag eingebunden und dem String
    				 * $this->viewOutput angehangen
    				 */
    				case ("ModelFloat") :
    					$this->viewOutput .= '<p>' .
    						 $retFromMethode [$desiredLanguage] .
    						 '</p>';
    					break;
    				default :
    			}
    		}
    		/**
    		 * die Rückgabe der Methode
    		 */
    		return $this->viewOutput;
    	}
    }
    
    "Hello World" Model View Controller (MVC): class ViewHtmlString{}
    + Klasse anzeigen - Klasse verbergen

Die Controller-Klasse Controller*

Die Controller-Klasse nimmt die durch den Benutzer angeforderten Anweisungen entgegen. Anhand der übergebenen Parameter, steuert der Controller die internen Prozesse, nimmt die formatierten Strings entgegen und gibt sie an den Benutzer wieder aus:

  • Klasse class Controller{...}

    Die class Controller sucht sich die geforderten Strings aus den Model-Klassen, übergibt sie an die class ViewString, nimmt das Ergebnis (return) entgegen und gibt diesen aus. Der Controller steuert also zwischen Bildschirm (Destkop), Model* und View*
    /**
     * Klassenname: Controller
     * Klassentyp nach MVC: Controller
     * Methoden ( function ):
     * - __construct() -> http://php.net/manual/de/language.oop5.decon.php
     * Eigenschaften / Property ( Variablen ):
     * - $arrObjModel( Type: Array )
     * - $arrObjHtmlString ( Type: Object )
     * - $output (Type: String)
     *
     * Projekt Aufgabe: Zusammenbau des HTML, String + HTML-Tags und dessen Rückgabe
     */
    class Controller {
    	protected $arrObjModel = array ();
    	private $objHtmlString;
    	public $output;
    	/**
    	 * beim Erzeugen eines Objekt der class controller{}, wird der Methode
    	 * (function) __construct() die Eigenschaft (Variable) $desiredLanguage
    	 * übergeben.
    	 */
    	public function __construct($desiredLanguage) {
    		/**
    		 * alle benötigten Objekte werden initialisiert
    		 */
    		$this->arrObjModel ["Navigation"] = new ModelNavigation ();
    		$this->arrObjModel ["TitleH1"] = new ModelTitleH1 ();
    		$this->arrObjModel ["Float"] = new ModelFloat ();
    		$this->objHtmlString = new ViewHtmlString ();
    		/**
    		 * $this->output nimmt die Rückgabe (return) aus der Methode
    		 * GeneratedHtmlString() des Objektes $this->objHtmlString() der class
    		 * ViewHtmlString{} entgegen.
    		 * Dazu werden dem Objekt $this->objHtmlString() zwei Eigenschaften
    		 * übergeben: $this->arrObjModel und $desiredLanguage
    		 */
    		$this->output = $this->objHtmlString->GeneratedHtmlString ( 
    			$this->arrObjModel, 
    			$desiredLanguage );
    		/**
    		 * Rückgabe
    		 */
    		return $this->output;
    	}
    }
    
    "Hello World" Model View Controller (MVC): class Controller{}
    + Klasse anzeigen - Klasse verbergen

Funktionsweise Programm "Hello World" mit Pattern Model View Controller (MVC) Schritt für Schritt Erklärung

Um die Schritte des Programmablauf "Hello World" im Model View Controller (MVC) Pattern nachzuvollziehen, kann es nützlich sein, das Skript auszudrucken.

  1. Variable $desiredLanguage der gewünschten Sprache wird befüllt

    Im ersten Schritt wird die über GET-Parameter der URL angeforderte Sprachausgabe in die Variable $desiredLanguage gespeichert.
    Wenn es keine Anfordeung über den GET-Parameter in der URL gegeben hat, also besipielsweise beim ersten Aufruf, wird der voreingestellte (default) Wert angenommen. Der voreingestellte Wert ist "deutsch"

    $desiredLanguage = "deutsch";
    $getLanguage = $_GET;
    switch ($getLanguage) {
    	case ($getLanguage != "") :
    		$desiredLanguage = key ( 
    			$getLanguage );
    		break;
    	default :
    }
    
    Script mvc.php: Wert (value) der Variable $desiredLanguage zuweisen
  2. Ein Objekt der Klasse class Controller{} initialisieren

    Ein Objekt der Klasse class Controller{} wird initialisiert. Bei der Intialisierung wird die Eigenschaft (Variable) $desiredLanguage dem Objekt übergeben. Das initialiserte Objekt wird in $objController gespeichert.

    $objController = new Controller ( 
    	$desiredLanguage );
    
    Script mvc.php: ein objekt der class Controller{} initialisieren
  3. Rückgabe aus Objekt $objController anfordern

    Die angeforderte Rückgabe (return) aus function __construct() im $objController wird in die Variable $html abegelegt.
    $html = $objController->output;
    
    Script mvc.php: Aufruf der Eigenschaft $output aus $objController

    Mit dem Aufruf der Eigenschaft $output aus dem Objekt $objController wird der Code der Methode function __construct() im $objController ausgeführt...

    Der ausgeführte Code der class Controller{}

    1. Eigenschaften (Variablen) werden definiert

      class Controller {
      	protected $arrObjModel = array ();
      	private $objHtmlString;
      	public $output;
      
      Script mvc.php → class Controller{}: Definieren der notwendigen Eigenschaften (Variablen)
    2. Objekte der benötigten Klassen werden initialisert

      	public function __construct($desiredLanguage) {
      		...
      		...
      		...
      		$this->arrObjModel ["Navigation"] = new ModelNavigation ();
      		$this->arrObjModel ["TitleH1"] = new ModelTitleH1 ();
      		$this->arrObjModel ["Float"] = new ModelFloat ();
      		$this->objHtmlString = new ViewHtmlString ();
      
      Script mvc.php → class Controller{}: Initialisieren von Objekten der notwendigen Klassen
    3. Aufruf der Methode function GeneratedHtmlString() im objHtmlString

      Mit dem Aufruf der Methode function GeneratedHtmlString() werden die Eigenschaften $arrObjModel und $desiredLanguage übergeben. Das Ergebnis (return) von function GeneratedHtmlString() wird in $this→output abgelegt.

      $this->output = $this->objHtmlString->GeneratedHtmlString ( 
      			$this->arrObjModel, 
      			$desiredLanguage );
      
      Script mvc.php → class Controller{}: Aufruf Methode function GeneratedHtmlString() aus $objHtmlString

      Der Aufruf der Methode Methode function GeneratedHtmlString() aus $objHtmlString löst den Programmablauf innerhalb des Objektes $objHtmlString aus...

      Der ausgeführte Code der class ViewHtmlString{}

      1. Objekt der class ViewHtmlString{}: Die notwendigen Eigenschaften werden definiert
        class ViewHtmlString {
        	protected $viewOutput;
        
        Script mvc.php → class ViewHtmlString{}: Eigenschaften werden definiert
      2. Rückgabe der Methode function RawString() aus den Objekten der Model*-Klassen

        Das übergebene Array $arrObjModel mit den Objekten der Model-Klassen wird innerhalb der Methode function GeneratedHtmlString() mit einer foreach() Schleife durchlaufen.
        Mit jedem Schleifendurchlauf wird aus dem zurückgegebenen Objekt (Array-Element) die Methode function RawString() ausfgerufen und in die Eigenschaft $retFromMethode gespeichert.
        Die Rückgabe von function RawString() ist das definierte Array innerhalb der Methode (function) des jeweiligen Objektes.

        public function GeneratedHtmlString($arrObjModel, $desiredLanguage) {
        		...
        		...
        		...
        		...
        		...
        		foreach ( $arrObjModel as $for ) {
        					...
        					...
        					...
        					...
        					$retFromMethode = $for->RawString ();
        
        Script mvc.php → class ViewHtmlString{}: Rückgabe der function RawString() wird in $retFromMethode abgelegt
      3. Rückgabe der Methode function RawString() aus den Objekten der Model*-Klassen

        Das jeweilige Objekt (Element) $for wird zur Ermittlung des Klassennamen an get_class() und zum Vergleich an switch() übergeben.

        switch (get_class ( 
        				$for )) {
        
        Script mvc.php → class ViewHtmlString{}: Rückgabe der function RawString() wird in $retFromMethode abgelegt
      4. Ausführung der Anweisung im case()

        Wenn der Klassename des Objektes mit dem im case() angegebenen Ausdruck übereinstimmt, wird die Anweisung innerhalb des case() ausgeführt. Das Ergebnis dieser Anweisung wird in $this->viewOutput gespeichert.

        case ("ModelNavigation") :
        					foreach ( array_keys ( 
        						$retFromMethode ) as $key ) {
        						$this->viewOutput .= "<a href=\"{$_SERVER['PHP_SELF']}?{$key}\">" .
        							 $retFromMethode [$key] .
        							 '</a> ';
        					}
        					break;
        
        Script mvc.php → class ViewHtmlString{}: Ausführung von Anweisung in case() und speichern in $viewOutput
      5. Ergebnis $this-viewOutput an return von function GeneratedHtmlString()

        Schließlich wird das Ergebnis $this->viewOutput an return übergeben und die Methode function GeneratedHtmlString() beendet.

        return $this->viewOutput;
        
        Script mvc.php → class ViewHtmlString{}: Übergabe von $viewOutput an return
      + zum Anzeigen des ausgeführten Programmcode hier klicken - zum Verbergen des ausgeführten Programmcode hier klicken

    4. Ergebnis (return) von function GeneratedHtmlString() im $this->output an return übergeben

      Die Eigenschaft $this->output des Objekt $objController hat nun den Wert der Rückgabe (return) aus $this->objHtmlString->GeneratedHtmlString () gespeichert und übergibt diesen an return von Methode function __construct() im $objController. Damit ist Methode function __construct() beendet.

      return $this->output;
      
      Script mvc.php → class Controller{}: Übergabe von $viewOutput an return
    + zum Anzeigen des ausgeführten Programmcode hier klicken - zum Verbergen des ausgeführten Programmcode hier klicken

  4. Ausgabe des gespeicherten Wert im $html

    echo $html;