[SIZE=4]Inhaltsverzeichnis[/SIZE]
[ol]
[li]Einleitung[/li][LIST=1]
[li]MVC[/li][li]Wieso MVC einsetzen?[/li][/ol]
[li]Tutorial: Gästebuch[/li][ol]
[li]Verzeichnisstruktur[/li][li]TemplateView-Pattern[/li][li]Der Controller[/li][li]Das Model[/li][li]Das View (=Template)[/li][li]Die Bootstrap-Datei[/li][/ol]
[/LIST]
[SIZE=5][B]
1. Einleitung[/B][/SIZE][INDENT]
[SIZE=4]1. MVC[/SIZE]
MVC ist die Abkürzung für Model View Controller. In der Objekt Orientierten Programmierung handelt es sich beim Model und beim Controller um eine Klasse, welche Methoden bereit stellen. Views sind nichts anderes als Templates, welche mit dem Dateiformat .phtml abgespeichert werden. Diese können PHP-Code beinhalten, dieser sollte aber so gut wie möglich dezimiert werden. Für Views sollte der Template-Syntax von PHP verwendet werden, da dieser die Übersichtlichkeit maßgeblich steigert.
Model
Das Model stellt Methoden bereit, mit die der Controller Daten aus Datein oder Datenbanken erhalten kann. Auch beinhaltet die Model-Klase Methoden, mittels die der Controller Daten in Datein oder Datenbanken eintragen kann.
Controller
Der Controller ist sozusagen das Verbindungsstück zwischen Model und View in einer MVC-Einheit (Eine große Applikation besteht oft aus mehreren MVC-Einheiten, welche z.B. auch als Module bezeichnet werden). Der Controller instanziiert mind. 2 Objekte: das Model und ein TemplateView (= ein „Design-Pattern“ oder auf deutsch „Entwurfsmuster“).
Der Controller ruft Methoden des Model-Objektes auf und speichert den Return-Wert dieser Methoden in einem Attribut des TemplateView-Objektes. Die Views/Templates werden innerhalb des TemplateView-Objektes eingebunden und können über dessen getter Methode auf die Daten zugreifen, die der Controller im TemplateView-Objekt gespeichert hat.
View
Ein View-Script ist nichts anderes als ein Template. Abgespeichert wird ein View meist mit der Dateiendung .phtml, da dort eben php und html drin steckt. Welches View in das TemplateView-Objekt eingebunden wird, entscheidet der Controller.
[SIZE=4]2. Wieso MVC einsetzen?[/SIZE]
Jeder PHP-Beginner erstellt für seine Projekte zahlreiche PHP Datein, welche sowohl aus PHP als auch HTML-Code bestehen. Sie vermischen das Display mit der Logik. Dadurch erhöht sich die Fehlerquote, Fehler können sich leichter einschleichen und schwerer ausfindig gemacht werden.
In MVC gibts es dagegen eine klare Trennung, man weiß auf der Stelle, wo man etwas findet. Zudem sind MVC Anwendungen, besonders im Objekt Orientierten Stil, sehr gut erweiterbar/abänderbar.
[/INDENT]
[SIZE=5]2. Tutorial: Gästebuch[/SIZE]
Wieso ich ein Gästebuch als Basis für dieses Tutorial gewählt habe ist leicht zu erklären. Für ein Gästebuch wird der Zugriff auf Datein/Datenbanken benötigt, in denen Gästebuch-Einträge gespeichert werden. Somit kommt das Model anhand eines reellen Beispieles zum Einsatz.
[SIZE=4]
[/SIZE][INDENT][SIZE=4]1. Verzeichnisstruktur[/SIZE]
wwwroot
-- [B]library[/B]
– class.TemplateView.php
-- [B]models[/B]
– guestbook.php
-- [B]views [/B]
– guestbook.phtml
-- [B]controllers[/B]
– guestbook.php
-- [B]css[/B]
– design.css
`-- index.php
[SIZE=4]
2. TemplateView-Pattern[/SIZE]
Der Code von wwwroot/library/class.TemplateView.php:
[PHP]<?php
class TemplateView {
private $template;
private $vars = array();
public function __construct($template) {
$this->template = $template;
}
public function assign($key, $value) {
$this->vars[$key] = $value;
}
public function __get($key) {
if (isset($this->vars[$key])) {
return $this->vars[$key];
}
return false;
}
public function render() {
ob_start();
$template = 'views/'. $this->template . '.phtml';
if (!is_file($template)) {
return 'Template not found!';
}
include $template;
$view = ob_get_clean();
return $view;
}
}[/PHP]
Der meiste Code sollte hier recht verständlich sein. Allerdings geht ich noch kurz auf die Method __get() ein. Dabei handelt es sich um eine Magische Interzeptor Method. Versuche ich z.B. in einem View-Script auf ein Eigenschaft zuzugreifen und existiert diese nicht bzw. sie ist als privat deklariert, dann wird automatisch diese magische Methode aufgerufen.
Beispiel:
Ich versuche folgendes im Template guestbook.phtml auszugeben:
[PHP]
<?php echo $this->foo; ?>
[/PHP]In unserer TemplateView-Klasse gibt es dieses Attribut (foo) nicht, wodurch die __get() Methode aufgerufen wird, dabei wird Ihr als Parameter foo übergeben: [FONT=courier new]__get(‚foo‘);[/FONT]
Der Vorteil dieser magischen Methode: wir sparen uns dadurch Code, wenn wir auf Daten zugreifen möchten, die im TemplateView abgelegt sind.
[SIZE=4]3. Der Controller[/SIZE]
Der Controller muss über 2 Methoden verfügen:
[/INDENT]
[ul][FONT=courier new]indexAction() // holt sich vom Model alle Einträge[/FONT][FONT=courier new]newEntryAction() // Sorgt dafür, dass das Model einen neuen Eintrag speichert[/FONT]
[/ul]
[INDENT]Was sucht das Action Postfix am Methodennamen? Der Controller ist eine Klasse. Dessen Methoden sind sogenannte Aktionen, welche man über URL Parameter aufrufen kann (dazu mehr in der Bootstrap-Datei (=index.php)).
Der Code von wwwroot/controller/guestbook.php:
[PHP]<?php
class guestbook_controller {
private $model = null;
private $view = null;
public function __construct() {
require 'models/guestbook.php';
require 'library/class.TemplateView.php';
$this->model = new guestbook();
$this->view = new TemplateView('guestbook');
}
public function indexAction() {
$entries = $this->model->getEntries();
$this->view->assign('entries', $entries);
return $this->view->render();
}
public function newEntryAction() {
if (isset($_POST['saveEntry']) && isset($_POST['name']) && isset($_POST['message'])) {
$entryDatas = array(
'Name' => trim($_POST['name']),
'Message' => trim($_POST['message']);
);
$this->model->saveEntry($entryDatas);
}
$this->indexAction();
}
}[/PHP]
Neben [FONT=courier new]indexAction()[/FONT] und [FONT=courier new]newEntryAction()[/FONT] habe ich noch einen Konstruktur ([FONT=courier new]__construct()[/FONT]) definiert. Dieser wird beim instanziieren des Controllers aufgerufen. Er erledigt die Aufgaben, die für alle Aktionen (actions) notwendig sind.
[SIZE=4]4. Das Model[/SIZE]
Unser Model benötigt zwei Methoden. Wie die heißen, sollte aus dem Code des Controllers schon vorhergehen:
[/INDENT]
[ul][FONT=courier new]getEntries()[/FONT] [FONT=courier new]// liefert alle Gästebuch-Einträge zurück[/FONT][FONT=courier new]saveEntry() // nimmt als Parameter ein Array entgegen, welches den Gästebuch-Eintrag repräsentiert und tragt den Eintrag in die Datenbank[/FONT]
[/ul]
[INDENT]
Der Code vom wwwroot/model/guestbook.php:
[PHP]<?php
class guestbook {
public function getEntries() {
$this->connectToDB();
$sql = „INSERT name
, message
FROM guestbook
“;
$result = mysql_query($sql);
$entries = array();
while ($row = mysql_fetch_array($result)) {
array_push($array, $row);
}
return $entries; // true|false
}
public function saveEntry(array $datas) {
$this->connectToDB();
$sql = "INSERT INTO `guestbook`
. "(`name`, `message`) VALUES "
('".mysql_real_escape_string($datas['Name'])."', '".mysql_real_escape_string($datas['Message'])."')";
$result = mysql_query($sql);
echo $result; // true|false
}
public function connectToDB() {
mysql_connect('localhost', 'Username', 'Password');
mysql_select_db('database');
}
}[/PHP]
[SIZE=4]5. Das View (=Template)
[/SIZE][/INDENT]
[INDENT]Das View-Script (wwwroot/views/guestbook.phtml) beinhaltet folgenden Code:
[PHP]
Gästebuch mit MVC
<?php if (is_array($this->entries) && count($this->entries) > 0) : ?>
<?php foreach ($this->entries as $entry) : ?>
<p>
<strong><?php echo $entry['name']; ?></strong>
<?php echo $entry['message']; ?>
</p>
<?php endforeach; ?>
<?php endif; ?>
<!-- Das Formular -->
<form action="index.php?controller=guestbook&action=newEntry" method="post">
<p>
Name<br />
<input type="text" name="name" />
</p>
<p>
Nachricht<br />
<textarea cols="40" rows="5"></textarea>
</p>
<p><input type="submit" name="saveEntry" value="Eintragen" /></p>
</form>
</body>
[/PHP]
[/INDENT]