Erste Schritte mit dem Zend Framework

5 | 2 Kommentare | 24271 Aufrufe
Sie können diese Wikiseite nach der Anmeldung auf Webmasterpro bearbeiten. Helfen Sie mit und verbessern Sie "Erste Schritte mit dem Zend Framework" mit Ihrem Wissen!

Anzeige Hier werben

Einführung

Ende 2005 begannen die Gespräche über ein neues PHP basiertes Framework, welches der Community frei zur Verfügung gestellt werden soll. Der Community wurde freie Mitbestimmung gegeben, welche Komponenten wie und mit welchen Funktionalitäten ins Framework aufgenommen werden soll. Dieses Vorhaben ist, wie man heute sehen kann, voll und ganz aufgegangen und daraus entstand das Zend Framework.

Aktuell stellt das Zend Framework Komponenten für MVC (Model-View-Controller), I18N (Internationalisierung) und L10N (Lokalisierung), einige Webservices und auch für die Erstellung eines Suchindexes mit Lucene. Das ist jedoch nur ein kleiner Teil der bereits vorhandenen Komponenten des Zend Frameworks.

Dieser Artikel soll nun eine Einführung sein, wie man sich schnell und einfach eine kleine Anwendung schreiben kann. Es wird hier vorerst nur um die grundlegende Struktur gehen, wie man mit dem Framework eine Webseite auf die Beine stellt.

Für die Verwendung der hier beschriebenen Anwendung, wird benötigt, dass Ihr Webserver mod_rewrite aktiviert hat und man die Konfiguration über eine .htaccess-Datei festlegen darf. Die Konfiguration Ihres Webservers und/oder des mod_rewrite Moduls ist nicht Teil dieses Artikels.

Inzwischen hat sich das Zend Freamework Team diesem Thema angenommen und eine eigene Möglichkeit entwickelt (s. Zend_Tool_Project und Zend_Tool_Framework), mit der eine komplette Zend Framework Anwendung erstellt und erweitert werden kann.

Dieser Artikel beschreibt, wie eine Zend Framework Anwendung, manuell, ohne die Zend_Tool-Komponenten, aufgesetzt werden kann.

Was brauche ich?

Es wird ein Webserver mit mindestens PHP 5.1.4 gebraucht. Der Webserver sollte mod_rewrite unterstützen und aktiviert haben. Das wichtigste ist natürlich das Zend Framework. Dies könnt ihr euch hier runterladen.

Ich habe für dieses Beispiel PHP 5.2.0, Apache 2.2 und das Zend Framework in der Version 1.5 (Preview Release) benutzt.

Die Verzeichnisstruktur

Als erstes einmal brauchen wir eine Verzeichnisstruktur, in der wir die Dateien unserer Anwendung ablegen. Schon über die Verzeichnisstruktur bekommt man eine sehr saubere Trennung zwischen Front- (Anzeige) und Backend (Verarbeitung).

Bild zu Erste Schritte mit dem Zend Framework

Für eine solch kleine Anwendung, sind das scheinbar schon sehr viele Verzeichnisse, könnte man nun denken, aber das ist kein Nachteil, sondern eher ein Vorteil, denn so bekommt man eine saubere Trennung der unterschiedlichen Dateien.

In das application-Verzeichnis können bei größeren Projekten Module angelegt werden. In unserem Fall brauchen wir jedoch keine Module, daher haben wir da direkt die drei Verzeichnisse controllers, models und views drin.

In das application/controllers-Verzeichnis kommen unsere Controller-Klassen hinein, welche die Anfragen annehmen und verarbeiten. Dort wird also entschieden, was gemacht werden soll, wenn z.B. die Url http://www.example.com/article/archive aufgerufen wird. In diesem Fall wäre article, der Name des Controllers, welcher die Anfrage verarbeiten soll. Was archive ist, erkläre ich gleich noch.

Das application/models-Verzeichnis bleibt in unserem Fall leer. Da werden normalerweise Model-Klassen abgelegt, mit denen der Zugriff auf bestimmte Daten erleichtert wird. Eine User-Klasse zum Beispiel, mit der man einen User anlegen, bearbeiten oder löschen kann, wäre eine Model-Klasse.

Im application/views-Verzeichnis legen wir unsere Tempates für die Anzeige ab. In das views-Verzeichnis ansich legen wir in unserem Fall nichts. Uns interessiert das darin liegende scripts-Verzeichnis und ganz besonders die Verzeichnisse darin.

Die Verzeichnisse im application/views/scripts-Verzeichnis stehen jeweils für die Controller unserer Anwendung. Templates, welche im Controller index gebraucht werden, legen wir in das Verzeichnis application/views/scripts/index. Wenn wir uns nochmal die Url von gerade vor Augen nehmen: http://www.example.com/article/archive. Wir hatten gesagt, dass article der Name des Controllers ist, welcher die Anfrage bearbeiten soll. Das archive dahinter definiert die Action, welche innerhalb des Controllers aufgerufen werden soll. Was nun genau eine Action ist, erkläre ich gleich näher.

Das etc-Verzeichnis brauchen wir in unserem Fall ebenfalls nicht. Dort werden normalerweise Konfigurationsdateien abgelegt mit Zugangsdaten für die Datenbank, Anzahl der Artikel pro Seite oder so.

Das library-Verzeichnis ist auch ein sehr interessantes Verzeichnis. Dort legen wir das Zend Framework ab (application/library/Zend). Nebenbei können wir dort Klassen ablegen, welche wir innerhalb in unserer Anwendung benötigen. Am besten geht man in diesem Verzeichnis genauso vor, wie auch beim Zend Framework mit den Verzeichnissen in Bezug auf die Klassennamen vorgegangen wird. Wir nehmen als Beispiel mal die Klasse Example_Controller_Action. Die Datei dazu würde nun im Verzeichnis library/Example/Controller/ liegen und Action.php heißen.

Das web-Verzeichnis ist ein wichtiges Verzeichnis, denn ohne dies geht garnichts bei unserem Beispiel. Wir haben nun Verzeichnisse mit Klassen, die die Anfragen verarbeiten und Verzeichnisse mit den Templates zur Ausgabe, aber wir brauchen natürlich noch etwas was wir im Browser aufrufen. Dafür ist das web-Verzeichnis zuständig. In unserem Beispiel liegen dort zwei Dateien. Zum einen die index.php welche über den Browser erreichbar sein wird und die .htaccess mit der wir mod_rewrite konfigurieren.

Der Document Root

Damit man über den Browser keinen Zugriff auf die Klassen, Konfigurationen etc. hat und die Verzeichnisse auch nicht irgendwie umständlich mit einer .htaccess schützen müssen, wird der Document Root auf das web-Verzeichnis gelegt. Somit ist der Zugriff über den Browser nur auf die Dateien möglich, die auch wirklich für den Browser bzw. dem Zugriff von Außen gedacht sind, möglich.

Den Document Root so zu legen, dass man keine Konfigurationen etc. über den Browser erreichen kann, ist keine Zend Framework spezifische Konvention! So sollte in jedem Projekt vorgegangen werden.

httpd.conf  
Apache Konfiguration
1
DocumentRoot /path/to/zfdemo/web

ACHTUNG: Sollte das Projektverzeichnis (/path/to/zfdemo) bereits in einem Unterverzeichnis eines gültigen Document Roots liegen sollte man die Verzeichnisstruktur anders gestalten, damit auch dann nicht auf die Konfigurationen etc. zugegriffen werden kann.

Der Code

Als nächstes schauen wir uns den Code an, welcher nötig ist, unsere Anwendung zum Laufen zu bringen. Als erstes nehmen wir uns die web/.htaccess-Datei vor, da diese mod_rewrite so konfiguriert, dass alle Anfragen an die index.php geleitet werden, da das Zend Framework für das Routen der Anfragen selbst zuständig ist. Wir nehmen in diesem Beispiel keine Rücksicht auf weitere Verzeichnisse im web-Verzeichnis, daher kommen wir zu einer solchen .htaccess-Datei:

web/.htaccess  
Apache Konfiguration
1
2
RewriteEngine On
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php

Somit werden nun schonmal all unsere Anfragen auf die index.php umgeleitet. Anfragen an Dateien mit den Endungen js, ico, gif, jpg, png und css werden jedoch weiterhin ganz normal behandelt. Diese Anfragen werden also nicht an die index.php umgeleitet.

Wie sieht nun die index.php aus? Ihr werdet euch sicher wundern, denn diese beinhaltet nur ein paar wenige Zeilen Code.

web/index.php  
PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php

require_once 'Zend/Controller/Front.php';

Zend_Controller_Front::getInstance()
    ->setControllerDirectory('../application/controllers')
    ->throwExceptions(false)
    ->dispatch();

?>

Der FrontController (Zend_Controller_Front) übernimmt die komplette Arbeit. Aber bevor ich genauer darauf eingehe, was dieser macht, erkläre ich erstmal was die Aufrufe darunter bedeuten. Mit dem Aufruf von setConntrollerDirecory() legen wir fest, wo sich unsere Controller befinden. Als nächstes setze ich throwExceptions() auf false, wieso? Ganz einfach, denn so wird im Fall eines Fehlers keine Exception geworfen sondern der ErrorController aufgerufen um unsere Fehlermeldung auszugeben. Der Aufruf von dispatch() sagt nur aus, dass es nun los geht. Der FrontController darf seine Arbeit aufnehmen und die Anfrage weiterleiten.

Der FrontController nimmt die aktuelle Anfrage an und lässt sie durch unsere Anwendung verarbeiten. Dabei wird die URL analysiert und das Routing beginnt. Das Routing ist dafür zuständig den korrekten Controller und dessen Action aufzurufen. Aktuell würde dies noch einen Fehler geben, da uns noch die benötigten Dateien (Controller-Klassen, Action-Templates etc.) fehlen. Als nächstes kommen die Controller ins Spiel.

Wir haben bei jeder Anwendung mindestens zwei Controller-Klassen. Den IndexController (application/controllers/IndexController.php) und den ErrorController (application/controllers/ErrorController.php).

application/controllers/IndexController.php  
PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
<?php

require_once 'Zend/Controller/Action.php';

class IndexController extends Zend_Controller_Action
{
    public function indexAction()
    {
        $this->view->exampleText = 'Hallo Welt.';
    }
    
    public function aboutAction()
    {
        $this->view->aboutText = 'Dies ist ein Beispiel aus dem Artikel '
                               . '"Erste Schritte mit dem Zend Framework"'
                               . 'auf http://www.webmasterpro.de/';
    }
}

?>

In jedem Controller (Zend_Controller_Action) hat man direkt einen View (Zend_View) zur Verfügung, welcher über $this->view angesprochen werden kann. Diesen kann man, wie man im Code des IndexControllers bereits sieht nutzen um Platzhalter für das Template zu definieren. In der Action indexAction des IndexControllers wird zum Beispiel der Platzhalter exampleText mit dem Wert "Hallo Welt." gefüllt. Dieser kann das innerhalb des Templates mit $this->exampleText angesprochen werden.

Unser IndexController beinhaltet nun zwei Actions. Zum Einen die indexAction, zum Anderen die aboutAction. Dies impliziert, dass wir nun auch zwei Templates brauchen. Für jede Action ein Template.

application/views/scripts/index/index.phtml  
HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Startseite</title>
    </head>
    <body>
        <h1>Startseite</h1>
        <p><?php echo $this->exampleText; ?></p>
        <h1>Navigation</h1>
        <ul>
            <li><a href="/index/about">Über</a></li>
            <li><a href="/index/test">fehlende Action</a></li>
            <li><a href="/test">fehlender Controller</a></li>
        </ul>
    </body>
</html>
application/views/scripts/index/about.phtml  
HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Über</title>
    </head>
    <body>
        <h1>Über</h1>
        <p><?php echo $this->aboutText; ?></p>
    </body>
</html>

Als nächstes benötigen wir noch den ErrorController inklusive dessen Template.

application/controllers/ErrorController.php  
PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<?php

require_once 'Zend/Controller/Action.php';

class ErrorController extends Zend_Controller_Action
{
    public function errorAction()
    {
        $errorHandler = $this->_getParam('error_handler');
        
        switch($errorHandler->type)
        {
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_CONTROLLER:
                $this->view->errorMessage = 'Controller konnte nicht gefunden werden.';
            break;
            
            case Zend_Controller_Plugin_ErrorHandler::EXCEPTION_NO_ACTION:
                $this->view->errorMessage = 'Action konnte nicht gefunden werden.';
            break;

            default:
                $this->view->errorMessage = 'Unbekannter Fehler aufgetreten.';
        }
    }
}

?>
application/views/scripts/error/error.phtml  
HTML
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
    "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
    <head>
        <title>Fehler</title>
    </head>
    <body>
        <h1>Fehler</h1>
        <p><?php echo $this->errorMessage; ?></p>
    </body>
</html>

Nun haben wir alles, was wir für unsere erste kleine Anwendung mit dem Zend Framework benötigen.

Am besten konfiguriert man den Webserver so, dass der DocumentRoot auf das web-Verzeichnis unserer Anwendung zeigt, sodass man über das Internet keinen Zugriff auf die Konfiguration bekommen kann. Dann könnt ihr die Anwendung testen, indem ihr http://localhost/ aufruft. Dann wird der IndexController mit der indexAction aufgerufen und ausgeführt.

Fragen und Antworten

Umständliche Templates!?

Man muss in jedem Template das komplette HTML-Gerüst schreiben? Was soll denn das?

Dies ist lediglich ein ganz einfaches Beispiel wie man mit dem Zend Framework eine kleine Anwendung aufsetzt. Natürlich kann man es auch anders machen, sodass man nicht in jedem Template das komplette HTML-Gerüst schreiben muss. Dabei hilft dann die Zend_Layout Komponente.

Projekt im Unterverzeichnis?

Mein Projekt liegt nicht direkt im DocumentRoot. Ich bekomme beim Aufruf die Fehlermeldung, dass der Controller XYZ nicht existiert.

Dies ist ganz einfach zu lösen. Man muss mit der Methode setBaseUrl() das Unterverzeichnis angeben, wo das Projekt aktuell liegt:

web/index.php (angepasst)  
PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<?php

require_once 'Zend/Controller/Front.php';

Zend_Controller_Front::getInstance()
    ->setControllerDirectory('../application/controllers')
    ->setBaseUrl('/pfad/zur/zfdemo')
    ->throwExceptions(false)
    ->dispatch();

?>

Nun kann die Anwendung über http://localhost/pfad/zur/zfdemo/ aufgerufen werden. Bitte achtet dabei auch darauf, dass die Links in den Templates angepasst werden, denn sonst werdet ihr Fehler bekommen, dass die Dateien/Verzeichnisse nicht gefunden werden.

Ich will mehr!

Wenn ich euer Interesse an dieses Framework geweckt habe, könnt ihr euch in der ausführlichen Dokumentation, mit vielen Beispielen, umschauen.

Verwandte Artikel


Wikiseite bearbeiten

Diese Seite kann von jedem registrierten Benutzer bearbeitet werden. Bisher haben 4 Personen an der Seite "Erste Schritte mit dem Zend Framework" mitgewirkt.

Sie haben einen Fehler entdeckt oder möchten etwas ergänzen? Dann können Sie nach der Anmeldung "Erste Schritte mit dem Zend Framework" hier bearbeiten.

Mitarbeiter

Kommentare: Erste Schritte mit dem Zend Framework

Neuen Kommentar schreiben
hmm
Beantworten

also erstens sollte das ZendFramework nicht unter Web liegen!!! sondern unter library oder so, und zweitens wird das für die wirklichen anfänger nicht gesagt das man das unter weblegen muss!

Marcel Domke am 05.03.2008 um 08:50
Re: hmm
Beantworten

also erstens sollte das ZendFramework nicht unter Web liegen!!! sondern unter library oder so, und zweitens wird das für die wirklichen anfänger nicht gesagt das man das unter weblegen muss!

Habe den Artikel angepasst.

Jan Pieper am 10.03.2008 um 13:56