Nachdem der letzte Beitrag das Model eines Objekts der Winzen-Datenbank vorgestellt hat, soll es heute um den zweiten und zentralen Bestandteil der Trias Model-View-Controller gehen. Und das ist der Controller, nicht der View. In der Reihung MVC spricht es sich besser, aber trotzdem gehört der Controller in die Mitte.
Der Controller ist das Herzstück der Anwendung. Seine Aufgabe ist, den Programmfluss zu steuern, alle Funktionalität bereitzustellen und zu verwalten. Er vermittelt zwischen der Daten-Schicht – dem Model und dem User Interface – dem View. Streng genommen liegt also alle Logik im Controller. Oder auch nicht, denn eigentlich will man die zentrale Schaltstelle nicht vollmüllen mit jedem kleinen Stück Funktionalität. Daher werden üblicherweise alle Aufgaben ausgelagert, die nicht für die Programmsteuerung notwendig sind und in Helfer (Helper oder Delegates) ausgelagert. Idealerweise baut man dabei diese Helfer gleich so, dass sie ihre Funktion auch dann erfüllen können, wenn man sie in anderen Programmen anspricht – don’t repeat yourself.
Der Controller für die Personen der Winzen-Datenbank sieht aktuell so aus: (Quellcode-Ansicht hier – Quellcode-Download hier)
class Person extends CI_Controller { public function __construct() { parent::__construct(); $this->load->model('person_model'); $this->load->model('eventnode_model'); $this->load->model('residence_model'); $this->load->helper('url_helper'); } public function index() { $data['person'] = $this->person_model->get_person(); $data['title'] = 'Winzen Datenbank'; //$this->load->view('header', $data); $this->load->view('person/index', $data); } public function view($pid = NULL) { $data['person_item'] = $this->person_model->get_person($pid); $data['person_events'] = $this->eventnode_model->get_eventnodesforperson($pid); $data['person_residences'] = $this->residence_model->get_residences($pid); if (empty($data['person_item'])) { show_404(); } $data['title'] = $data['person_item']['FirstName']; $data['title'] += $data['person_item']['LastName']; $this->load->view('person/view', $data); } }
Das ist schon ein bisschen mehr als im Model, aber immer noch zahm und überschaubar, wenn man bedenkt, was alles passiert.
Den Rahmen kennen wir schon: Eine Klasse Person erweitert einen generellen Bauplan von CodeIgniter(CI)-Controllern. Es folgt im ersten Block geschweiften Klammern der Konstruktor, der immer dann läuft, wenn der Controller instanziiert wird. Streng genommen läuft nämlich gar nicht DER Controller, sondern für jeden Webseitenaufruf EIN Controller vom Typ Person-Controller. Dieser wird jedes Mal frisch erzeugt und beim Erzeugen (sprich: dem Vorbelegen der Inhalte) läuft der Konstruktor. Und der macht Zeile für Zeile folgendes:
- Er ruft den Konstruktor des Eltern-Objekts auf. Der Person-Controller erbt von CI_Controller, also wird der Konstruktor von CI_Controller ausgeführt und sorgt dafür, dass alles, was vererbt wird, auch wirklich da ist.
- Nacheinander wird jetzt das Model der Objekte Person (Personen), EventNodes (Knotenpunkte des Zeitstrahls) und Residence (Wohnsitze) geladen. Wie gehabt: Es läuft deren Konstruktor, so dass als Methoden zum Laden und Speichern von Daten bereit stehen. Abschließend wird der Url-Helper geladen – ein kleines Programmschnipselchen, mit dem URLs in Links gebaut werden können.
Den zweiten Block bildet die Index-Methode – es ist Konvention von CodeIgniter, dass diese Methode immer dann aufgerufen wird, wenn keine weiteren Parameter angegeben werden. CodeIgniter-Links funktionieren immer so:
www.domain.org/index.php/controllername/methodenname/parameter
Die Index-Methode kommt also zum Einsatz, wenn winzen.danielstange.de/index.php/person/index angefordert wird. Und da es in CodeIgniter auch eine Default-Route gibt, habe ich die Default-Route auch auf diesen Pfad gelegt, damit als Erstes immer die Übersicht aller Namen kommt.
Die Index-Methode macht nun folgendes:
- Sie erzeugt ein Daten-Feld (sagt man glaube ich in Deutsch) – ein mehrdimensionales assoziatives Array. Klingt krass, ist es aber nicht. $data ist die Variable, mit zwei Schlüsselworten: Person und Title.
- Zuerst wird die Methode get_person() von Person_model aufgerufen und ihr Ergebnis in $data[‚Person‘] geladen. Wir erinnern uns: Das ist die Methode, um alle Datensätze aus der Tabelle Person zu laden. Also können wir jetzt mit dem Schlüssel „Person“ alle Datensätze zu Personen aus $data holen.
- Dann wird der Schlüssel „Title“ auf „Winzen-Datenbank“ gesetzt.
- Es folgt eine Zeile mit Doppel-Slashes: // und diese Zeile wird nicht ausgeführt. Es handelt sich um einen Zeilenkommentar, der hier benutzt ist, um Code abzuschalten („auszukommentieren“)
- Schließlich wird – das ist jetzt nichts Neues mehr, wieder etwas nachgeladen, nämlich ein View. Es handelt sich um den View person/index (eine Seitenvorlage für die Index-Ansicht des Person-Objekts und diesem wird der Wert von $data übergeben. Das ist gewissermaßen der Auftrag, eine Webseite anzulegen und anzuzeigen.
Die zweite Methode funktioniert ganz ähnlich, sie heißt view() und erzeugt die Einzelansicht eines Datensatzes. Sie empfängt eine Person-ID in die Variable $PID und holt damit zunächst einen einzelnen Datensatz aus der Tabelle Person, dann alle Zeitleisten-Einträge zu dieser Person und alle Wohnsitze dieser Person. Schlussendlich wird dann wieder ein View beauftragt, eine Seite herzustellen (zu rendern) – person/view mit den gesammelten Werten, die Wieder in $data einsortiert wurden.
Eigentlich recht überschaubar, wenn man das Prinzip verstanden hat. Nächster Post: Der View.