Zend Framework 2: Installation und erste Einblicke
Die Skeleton-Applikation
Zend2 ist ein Framework. Das heisst es stellt einem nicht wie eine Library nur bereits vorgefertigte Funktionen zur Verfügung. Es gibt einen Rahmen vor, wie man damit programmieren sollte. Die Zend2-Entwickler haben sich hier eine sehr einfache Möglichkeit ausgedacht, wie sie ihre Vorstellungen von einer typischen Zend2-Applikation an die Entwickler weitergeben. Eine Skeleton-Applikation, d.h. eine zwar vollständige lauffähige, aber doch sehr kleine Applikation. Sie gibt eine sinnvolle Verzeichnisstruktur vor und enthält bereits die Grundkonzepte des Frameworks. Auf dieser Basis kann man mit dem nötigen Wissen über Zend2 sehr schnell zu einer Applikation kommen. Die Skeleton-Applikation kann man auf verschiedene Weisen aufsetzen. Eine davon funktioniert so:
- Herunterladen der Software
- Die Zend-Library (ZF2 Full) -> http://framework.zend.com/downloads/latest
- Die Skeleton-Applikation -> https://github.com/zendframework/ZendSkeletonApplication
-
Entpacken Sie die Software in einem temporären Verzeichnis
- tar -xvzf ZendFramework-2.3.3.tgz
- unzip ZendSkeletonApplication-master.zip
-
Verschieben Sie das Unterverzeichnis library aus der ZF2-Bibliothek in das Verzeichnis der
Skeleton-Applikation
- mv ZendFramework-3.3.1/library/ ZendSkeletonApplication-master/
- Konfigurieren Sie die Skeleton-Applikation so, dass sie die Zend-Library korrekt findet
- Datei ZendSkeletonApplication-master/init_autoloader.php öffnen
- Zeile 28 ändern zu -> $zf2Path = ‚library‘;
- Das Verzeichnis mit der Skeleton-Applikation so verschieben und umbenennen, dass neuesVerzeichnis/public zum DocumentRoot-Verzeichnis der Apache-Konfiguration wird.
- Im Web-Browser aufgerufen, sollte sich folgendes Bild ergeben
Achtung: Ist das obige Bild unter der Adresse http://localhost zu erreichen, muss es auch unter der Adresse http://localhost/application erreichbar sein. Ist dies nicht der Fall ist der Apache nicht korrekt konfiguriert! Jetzt da wir eine funktionierende Zend2-Applikation haben, können wir uns nach Herzenslust durch den Code wühlen und dabei Zend2 immer besser verstehen lernen. Ich werde dazu hier in 2 Schritten vorgehen
- Ich werde versuchen, die Zend-Applikation weiter zu vereinfachen, um die Struktur der Applikation noch weiter zu verdeutlichen und begreifbar zu machen.
- Ist die Struktur dann klar geworden, werde ich mir einzelne Themen herauspicken und den Code so wieder erweitern.
Die Vorgehensweise sollte im folgenden so sein:
- Jeder sollte Teil 1 durchgehen, um die Grundstruktur der Zend2-Applikation verstanden zu haben.
- Danach kann man sich aus Teil 2 das herauspicken, was einen gerade interessiert und es neu lernen oder erneut nachschlagen
Also viel Spass damit.
Verzeichnisstruktur
Das neu geschaffene Verzeichnis ist komplizierter als es sein müsste. Das liegt daran, dass es für mehrere Eventualitäten bereits gerüstet ist. So ist zum Beispiel schon vorgesehen die neuesten Updates jederzeit über Git herunterzuladen, oder zusätzliche Plugins oder gar andere Libraries in die Applikation zu integrieren. Baut man solche Möglichkeiten erstmal aus, wird die ganze Sache wieder ein Stück übersichtlicher.
- .gitignore .gitmodules: diese Dateien werden nur gebraucht, wenn man seinen Code in Zukunft mit Git verwalten will -> löschen
- composer.json composer.phar: dieser Dateien werden nur gebraucht, wenn man seinen Code in Zukunft mit composer verwalten will -> löschen
- vendor: Unterverzeichnist das vom composer verwendet wird -> löschen
- README.md: beschreibt, die beiden oben genannten alternativen Installationswege -> löschen
- LICENSE.txt: die Lizenz unter der man die Software bekommen hat
- config: globale Konfigurationsdateien kommen in dieses Verzeichnis
- init_autoloader.php: in dieser Datei wird der Autoloader der Library konfiguriert
- module: hier sind die Module der Applikation und da unter Zend2 alles in einem Modul ist, ist hier also die gesamte Applikation
- data: Verzeichnis für vielerlei Zwecke (z.B.temporäre Dateien, DatenFiles, …)
- library: die Zend-Library
- public: das öffentliche Verzeichnis, dessen Inhalt durch den Webserver sichtbar ist.
Das Verzeichnis config
Hier befinden sich die Konfigurationsdateien mit globalem Inhalt wie z.B. Datenbankzugängen. Für meine minimalistische Applikation bleiben hier 2 Dateien übrig
- application.config.php Diese Datei enthält in der minimalistischen Version den Hinweis, welche Module die Applikation hat (nämlich nur das Modul Application), wo diese zu finden sind (im Verzeichnis module) und wo die Dateien für weitere globale Konfigurationsdateien sind (im Verzeichnis config/autoload)
<?php return array( 'modules' => array( 'Application', ), 'module_listener_options' => array( 'module_paths' => array( './module', ), 'config_glob_paths' => array( 'config/autoload/{,*.}{global,local}.php', ), ), );
- autoload/global.php Wie bereits erwähnt ist dies eine der Dateien, die weitere Konfigurationen enthalten kann. Meine minimalistische Applikation hat solche weitere Konfigurationen noch nicht. Deshalb ist diese Datei recht kurz
<?php return array();
Das Verzeichnis public
.htaccess
Wie bereits erwähnt ist dies das Verzeichnis, das vom Web aus zu sehen ist. Die Datei .htaccess veranlasst, dass jede Anfrage an die Datei index.php weitergereicht wird. Apache-Konfiguration ist nicht Teil dieses Tutorials. Wer mehr über die Rewrite-Engine von Apache erfahren will, schaut am besten in der Original-Doku nach.
index.php
Doch zurück zur index.php. Wenn man sich deren Inhalt anschaut, ist man vielleicht etwas überrascht, weil sie nur wenige Zeilen lang ist. Bevor ich jedoch auf die einzelnen Zeilen eingehe, zuerst noch ein weiterer Schritt zur Vereinfachung der Software. In der index.php wird die Datei init_autoloader.php eingefügt. Diese Datei konfiguriert den Autoloader-Mechanismus für alle Eventualitäten, die Auftreten könnten, wie zum Beispiel Fremdmodule, die ihren eigenen Loading-Mechanismus mitbringen. Baut man alle Eventualitäten aus, die fürs erste nicht interessieren, wird die Datei sehr kurz. Ich habe mich deshalb dazu entschlossen, die init_autoloader.php zu löschen und deren Inhalt in die index.phpeinzubauen. Das Ergebnis sieht wie folgt aus:
<?php /** * This makes our life easier when dealing with paths. Everything is relative * to the application root now. */ chdir(dirname(__DIR__)); // Setup autoloading include 'library/Zend/Loader/AutoloaderFactory.php'; Zend\Loader\AutoloaderFactory::factory(array( 'Zend\Loader\StandardAutoloader' => array( 'autoregister_zf' => true ) )); // Run the application! Zend\Mvc\Application::init(require 'config/application.config.php')->run();
Die Funktionen der einzelnen Zeilen ist schnell erklärt
- zuerst wird mit chdir in das Wurzelverzeichnis der Applikation gewechselt. Dies macht alle weiteren Pfadangaben leichter, da in den meisten Fällen ein ../ entfällt.
- danach wird mit include ein Autoloader-Mechanismus geladen und in der darauffolgenden Zeile gleich konfiguriert und gestartet. Ab dieser Zeile benötigt man nirgendwo in der Applikation mehr die Befehle include oder require, da alle benötigten Dateien vom Autoloader geladen werden. Diese wenigen Zeilen genügen, um die ganze Zend-Library laden zu können. Wie man dafür sorgt dass auch selbst geschriebene oder fremde Modul-Klassen gefunden werden, folgt in den weiteren Kapiteln
-
die ganze Magie des Zend-Framework passiert in der letzten Zeile.
- init: Hier wird die Applikation hochgefahren. Dazu wird die Konfigurationsdatei übergeben
- run: Hier wird die Applikation gestartet. Hierzu später mehr.
Sonstiges
Die Zend-Skeleton-Application enthält Bootstrap, mit dem man schnell sehr ansprechende Webseiten erstellen kann. Obwohl Bootstrap für eine vollständige Webseite sehr empfehlenswert ist, will ich mich hier von möglichst wenig Dingen ablenken lassen. Deshalb lösche ich mal alles in diesem Verzeichnis, bis auf die Datei index.php
Das Verzeichnis module/Application
Das Verzeichnis module enthält die Module aus der die Applikation zusammengesetzt ist. Da eine Zend2-Applikation nur aus Modulen zusammengesetzt ist, beherbergt dieses Verzeichnis also die gesamte Applikation, abzüglich der Konfigurationsdateien und Dateien, die wenig mit PHP zu tun haben, wie CSS- und Javascript-Dateien. Die Skeleton-Applikation hat nur ein Modul Application. Dies ist ein ganz normales Modul, wie all die anderen Module, die noch kommen werden. Die einzige Besonderheit dieses Moduls besteht darin, dass es als erstes Modul der Applikation auch applikationsweite Dinge enthält, wie z.B. das globale Template der Applikation. Sieht man sich die Verzeichnisstruktur dieses Moduls an, sieht man, wie viel Funktionalität in diese Beispiel-Applikation bereits eingebaut ist. Das Unterverzeichnis language enthält Sprachdateien, mit deren Hilfe man mehrsprachige Seiten verwirklichen kann. Um dieses Beispiel zu vereinfachen löschen wir dieses Verzeichnis. Die Applikation funktioniert auch ohne dieses Verzeichnis wie bisher. Der restliche Unterverzeichnis besteht dann noch aus folgendem
die Datei Module.php
Diese Datei wird vom Module-Loader benötigt. Sie enthält
- Angaben wie beim Hochfahren der Applikation mit dem Modul umgegangen werden muss (onBootstrap)
- wo die Konfiguration für dieses Modul zu finden ist
- wie man die Klassen dieses Modules findet.
<?php namespace Application; use Zend\Mvc\ModuleRouteListener; use Zend\Mvc\MvcEvent; class Module { public function onBootstrap(MvcEvent $e) { $eventManager = $e->getApplication()->getEventManager(); $moduleRouteListener = new ModuleRouteListener(); $moduleRouteListener->attach($eventManager); } public function getConfig() { return include __DIR__ . '/config/module.config.php'; } public function getAutoloaderConfig() { return array( 'Zend\Loader\StandardAutoloader' => array( 'namespaces' => array( __NAMESPACE__ => __DIR__ . '/src/' . __NAMESPACE__, ), ), ); } }
die Datei config/module.config.php
Diese Datei enthält die Konfiguration für die Dienste, die dieses Modul zur Verfügung stellt
- Routing-Informationen die einem URL-Path einem Controller und einer Action zuordnen
- Controller-Definition, die einem Controllernamen die entsprechende Klasse zuordnen
- View-Manager, die definieren, wo die HTML-Templates des Moduls zu finden sind.
<?php return array( 'router' => array( 'routes' => array( 'home' => array( 'type' => 'Zend\Mvc\Router\Http\Literal', 'options' => array( 'route' => '/', 'defaults' => array( 'controller' => 'Application\Controller\Index', 'action' => 'index', ), ), ), ), ), 'controllers' => array( 'invokables' => array( 'Application\Controller\Index' => 'Application\Controller\IndexController' ), ), 'view_manager' => array( 'template_path_stack' => array( __DIR__ . '/../view', ), ), );
die Datei src/Application/Controller/IndexController
Hier wird die eigentliche Arbeit des Moduls erledigt. Die Anfrage wird hier entgegengenommen, verarbeitet und das Ergebnis an die HTML-Templates zur optischen Aufbereitung übergeben. In unserem einfachen Beispiel sieht dies so aus
<?php namespace Application\Controller; use Zend\Mvc\Controller\AbstractActionController; class IndexController extends AbstractActionController { public function indexAction() { return array( 'title' => 'Zend2 Skeleton Application', 'message' => 'This is a very minimalistic Zend2 Application' ); } }
dem Verzeichnis view
Dieses Verzeichnis enthält alle HTML-Templates, die nötig sind um das Ergebnis der Anfrage in eine korrekte HTML-Seite zu verwandeln. In unserem Besipiel sind dies 2 Dateien
- layout/layout.php diese Datei enthält das globale Template mit den HTML-, HEAD- und BODY-Tags. Jedes weitere Template fügt seinen Inhalt in den BODY-Tag dieses Templates ein
<!DOCTYPE html> <html lang="en"> <head> <meta charset="utf-8"> <title>Zend2 Skeleton</title> </head> <body> <?php echo $this->content; ?> </body> </html>
- application/index/index.php das Template für den Controller Application und die Action index
<h1><?php echo $this->title ?></h1> <p><?php echo $this->message ?></p>
Die Verzeichnisse data und library
Diese Verzeichnisse sollen hier nur kurz erwähnt werden, da wir uns darin nur selten aufhalten werden.
- data ist ein Verzeichnis für temporäre Dateien oder Dateien, die thematisch in kein anderes Verzeichnis gehören, wie z.B. File-Uploads
- library ist das Unterverzeichnis für die Zend-Library und andere PHP-Libraries, falls die Applikation diese benötigt.
Zusammenfassung
Am Ende dieses Kapitels ist nun die Applikation auf ein Minimum reduziert. An diesem Minimum lässt sich besonders gut nun die prinzipielle Funktionsweise des Zend-Frameworks erläutern. Nach dieser Erklärung geht es dann in weiteren Kapiteln um weiterführende Themen, wie man nun aufbauend auf diese Minimal-Applikation eine vollständige Web-Applikation bauen kann.
- Weiter mit Arbeitsweise des Zend-Framework