Fritz Thomas

28 Jan, 2008

Zend Framework How-To Teil 1: Projektaufbau, Konventionen und modulare Verzeichnisstruktur

Posted by: Fritz Thomas In: Zend Framework

Das ist der erste Teil meiner Tutorial oder How-To Serie für das Zend Framework.
Dieser erste Artikel wird etwas früher als mit der Implementierung des bootstrapping Prozesses oder dem Erstellen neuer Controller, Models oder Views beginnen. Ich werde hier als erstes grundlegende Gedanken und Überlegungen in den Raum stellen, die man sich vor der Implementierung stellen sollte – wie zum Beispiel die Wahl der richtigen Verzeichnisstruktur und die Ausarbeitung eigener Konventionen.

Wozu die ganze Theorie?

Die Wahl der Verzeichnisstruktur oder das überlegen und / oder aufschreiben eigener Konventionen mag im ersten Moment vielleicht etwas nebensächlich erscheinen und auch so behandelt werden, doch will man eine Applikation von vorn herein so modular wie möglich aufbauen um später nicht mehr Arbeit zu haben um neue Features (Module, Plugins, Controller, I18N, Caching, Suche, etc..) zu implementieren sollte man sich etwas mehr Zeit nehmen um über die jetzigen und auch die zukünftigen Anforderungen an die Applikation, nachzudenken. Die Wichtigkeit dessen steigt, um so mehr Entwickler an einem Projekt beteiligt sind, da darauf um so mehr zu achten ist, dass jeder Entwickler weiß welche Code Conventions einzuhalten sind, und vor allem WIE (und nicht ob!!!) dokumentiert werden muss.

Analyse der Anforderungen

Jeder Entwickler, der das eine oder andere größere Projekt fertig gestellt hat, weiß das genaue ausgedehnte Analysen zu Beginn der Entwicklung nicht verschwendete Zeit ist. Vorausgesetzt man nutzte die Zeit auch wirklich produktiv! ;-)

Als erstes sollte man darüber nachdenken welche Anforderungen an das Projekt gestellt werden:

  • Soll das Projekt über eine Suche verfügen?
  • Soll sie Mehrsprachige Texte zur Verfügung stellen (Stichwort – Internationalisation oder I18N)?
  • Wenn es eine im Internet öffentlich zugängliche Seite ist, wieviele Hits werden erwartet (Stichwort: Caching)?
  • Welche Features sind für die Zukunft geplant?
  • Wer und wieviele Entwickler werden an dem Projekt arbeiten?
  • Wie soll daher der Sourcecode verwaltet werden?

Keine Sorge, ich werde nicht auf jede einzelne Frage eingehen. Sie sollten eher als Gedankenanstoß gedacht sein. Es macht aber durchaus Sinn sich zu Beginn solche Fragen zu stellen und im Team zu besprechen und dazu alle Ideen, Bedenken und Vorschläge aufzuschreiben. Einige im Team sind optimistisch, andere wieder pessimistisch – genau die Mischung finde ich kann sich sehr positiv auf ein Projekt auswirken. Was das Brainstorming in einem Team betrifft habe ich die Ratschläge von Zack Urlocker sehr nützlich gefunden.

Programmierpraktiken und Konventionen

Aufgrund der gewonnen Erkenntnisse die man aus den Überlegungen zu Beginn und aus vorigen Projekten erlangt hat sollte man, auch wenn man alleine entwickelt, sich einerseits über vorhandene Konventionen informieren und andererseits sich eigene Programmierpraktiken (Best Practices) und Konventionen aneignen.

Dabei sollte man sich die in der Praxis als gut bewährten stets behalten und an denen, die sich als schlecht herausgestellt haben, arbeiten und verbessern. Das klingt schon wieder so theoretisch, aber ich denke Ihr wisst was ich meine.

Natürlich sollte man das ganze nicht übertreiben und jedes einzelne Detail bestimmen und festlegen. Vor allem in einem Team von Entwicklern muss es auch gestattet sein Ausnahmen von den Konventionen zu machen sofern sie die Lesbarkeit und Wartbarkeit des Codes nicht verschlechtern.

Eine konkrete ‘Konvention’ wäre zum Beispiel das man die Konfiguration für eine Komponente (Action_Helper, View_Helper, etc…) immer mit dem Klassennamen als Key in der Zend_Config oder in der Zend_Registry speichert oder aber auch das man jedes Modul als geschlossene Einheit betrachtet und es auch so entwickelt das man sie in anderen Applikationen wieder verwenden kann.

Ein andere Konvention an die man sich in seinen Projekten durchgehend halten sollte wäre die Verzeichnisstruktur.

Verzeichnisstruktur

Die Verzeichnisstruktur macht es unter anderem (”Programmierpraktiken und Konventionen”) leichter vorhandene Module in weiteren Projekten mit wenig oder gar keinem Aufwand wieder zu verwenden. Und das sollte doch das Ziel eines jeden Entwicklers sein, oder wer erfindet schon gerne das Rad immer wieder neu? :-)

Eine solche modulare Verzeichnisstruktur könnte so aussehen:

application/
htdocs/
library/

Der Document_Root des WebServers ist hier ‘htdocs/’. Das Zend Framework und evtl. andere Librarys sind im Verzeichnis ‘library/’ zu finden. Der include_path sollte auch entsprechend für dieses Verzeichnis gesetzt sein und muss nicht zwingend im selben Verzeichnis wie htdocs und application sein. Die eigentlichen Dateien und Verzeichnisse der Applikation liegen in ‘application/’. Das erleichtert es auch den Sourcecode zu verwalten und später das Aktualisieren der fertigen Applikation.

Der Inhalt des ‘application/’ Verzeichnisses:

bootstrap.php
config/
layouts/
library/
log/
modules/
temp/

bootstrap.php

In der bootstrap.php findet das eigentliche Initialisieren der Applikation statt. In der index.php im ‘htdocs/’ Verzeichnis wird ‘bootstrap.php’ lediglich ‘required’:

htdocs/index.php:

< ?php
require '../application/bootstrap.php';

wie schon erwähnt, in der bootstrap.php findet das eigentlich bootstrapping statt:

application/bootstrap.php:

< ?php
$applicationPath = dirname(__FILE__);
define('APPLICATION_PATH', $applicationPath);
unset($applicationPath);
 
require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload();
 
$front = Zend_Controller_Front::getInstance();
$front->addModuleDirectory(APPLICATION_PATH . DIRECTORY_SEPARATOR . 'modules');
$front->dispatch();

In Zeile 3 wird eine Konstante mit dem absolute Pfad des application Verzeihnisses angelegt. Das ermöglicht es anderen Komponenten oder Modulen im Kontext des application Verzeichnisses zu arbeiten. Zum Beispiel Log Dateien schreiben, Ausgaben cachen, oder aber auch in einem Modul Unterverzeichnis Dateien auszulesen. Um zum Beispiel im Modul ‘Filesystem’ ein Unterverzeichnis ‘files/’ auszulesen:

Da in der index.php nur eine einzige Zeile PHP Code, im einzigen nach aussen offenen Verzeichnis ‘htdocs/’, zu finden ist, wird ausserdem bei einem nicht richtig funktionierenden Webserver, der den Inhalt von php Dateien ausgibt anstatt den Code auszuführen, verhindert das viele Informationen preisgegeben werden.

modules/filesystem/controllers/IndexController.php:

< ?php
require_once 'Zend/Controller/Action.php';
 
class Filesystem_IndexController extends Zend_Controller_Action
{
 
    /**
     * The default action - show the home page
     */
    public function indexAction ()
    {
        $directory = APPLICATION_PATH . DIRECTORY_SEPARATOR . 'modules' . DIRECTORY_SEPARATOR . 'filesystem' . DIRECTORY_SEPARATOR . 'files';
        $res = opendir($directory);
        $contents = array(
        );
        if (false !== $res) {
            while (false !== ($content = readdir($res))) {
                if ($content !== '.' && $content !== '..') {
                    $contents[] = $content;
                }
            }
        }
        $this->view->contents = $contents;
    }
 
}

So ist es möglich alle zu einem Modul gehörenden Files im Modul Verzeichnis zu verwalten. Installiert man dieses Modul in einer Applikation müssen so keine Anpassungen vorgenommen werden oder irgendwelche Pfade und Variablen zu den Pfaden angepasst werden.

config/

Wie der Name schon vermuten lässt werden hier globale Konfigurationen die in der gesamten Applikation gültig sind gespeichert. Egal ob es sich dabei um eine ini Datei handelt oder um eine xml Datei.

‘application/library/’

Das ‘application/library/’ Verzeichnis kann dazu verwendet werden vorhandene Klassen im globalen ‘library/’ Verzeichnis zu überladen. Das ermöglicht es auf Servern wo mehrere unterschiedliche ZF Applikationen gehostet sind und gemeinsam eine Library nutzen, einzelne Klassen des Zend Frameworks oder der eigenen Library zu überladen. Dazu sollte mittels set_include_path() in der bootstrap.php der Pfad an die erste Stelle gesetzt werden:
bootstrap.php:

< ?php
$applicationPath = dirname(__FILE__);
define('APPLICATION_PATH', $applicationPath);
unset($applicationPath);
 
require_once 'Zend/Loader.php';
Zend_Loader::registerAutoload();
 
$oldIncludePath = get_include_path();
$localLibraryDir = APPLICATION_PATH . DIRECTORY_SEPARATOR . 'library';
set_include_path($localLibraryDir . PATH_SEPARATOR . $oldIncludePath);
 
$front = Zend_Controller_Front::getInstance();
$front->addModuleDirectory(APPLICATION_PATH . DIRECTORY_SEPARATOR . 'modules');
$front->dispatch();

log/

Log Dateien der Applikation. Modul Log Files sollten ebenfalls in diesem Verzeichnis gespeichert werden. Hier sollten nicht die Apache Log Files geloggt werden.

modules/

Alle Zend Framework Module werden hier drin gespeichert.
Ein einzelnes Modul sollte nach diesem Muster aufgebaut sein:

Modulverzeichnisstruktur:

default/
    config/
    controllers/
    models/
    views/
       helpers/
       filters/
       scripts/
       layouts/

Die Bedeutung der einzelnen Verzeichnisse sollte soweit klar sein.

temp/

In diesem Verzeichnis sollten alle temporären Dateien, wie zum Beispiel caching files fuer Zend_Cache, oder auch das ‘templates_c’ Verzeichnis von Smarty, gespeichert werden. PHP Sessions sollten sollten nicht hier gespeichert werden, weil es das Auslesen vorhandener Sessions erleichtern würde, in dem Fall das die Applikation durch einen Fehler es ermöglicht fremden Code auszuf¨hren.


Im nächsten Teil meines Zend Framework Tutorial werde ich anhand einer Beispiel Applikation die Verwendung von Zend_Layout und den neuen Zend_View_Helpern Placeholder, Partial und Action erklären.


Welche Verzeichnisstruktur verwendet Ihr? Was haben Eure Erfahrungen gezeigt? Ich denke es würde allen Lesern interessieren.

  • Digg
  • del.icio.us
  • DZone
  • MisterWong
  • Reddit
  • Slashdot
  • Technorati
  • YahooMyWeb
  • Fark
  • Google Bookmarks

8 Responses to "Zend Framework How-To Teil 1: Projektaufbau, Konventionen und modulare Verzeichnisstruktur"

1 | hype.yeebase.com

February 2nd, 2008 at 2:15 pm

Avatar

Zend Framework Tutorial Teil 1 (deutsch)…

Der Webentwickler Thomas hat eine Tutorial oder HowTo Serie zum arbeiten mit dem Zend Framework gestartet. Im ersten Teil geht es um: Projektaufbau, Konventionen und modulare Verzeichnisstruktur…

2 | Alexander

February 10th, 2008 at 9:47 pm

Avatar

Ich freue mich schon auf das nächste Tutorial!

3 | butters

February 12th, 2008 at 3:52 pm

Avatar

da kann ich mich alexander nur anschließen, ist mal gut zu lesen…

4 | ninsky

February 23rd, 2008 at 9:54 pm

Avatar

..das Tutorial hat mir gut gefallen! Bin gespannt auf die “Zend_Layout”-Fortsetzung…!

5 | Hans Wurst

February 29th, 2008 at 11:20 pm

Avatar

Hi

ich warte auf den nächsten Teiul, kann kaum schlafen :-)

Bitte schnell

:-)

Super Arbeit :-)

6 | Bosko

March 4th, 2008 at 11:48 pm

Avatar

Ich freue mich auch auf das nächste Tutorial.
Danke vielmal

7 | rad get application path

July 10th, 2008 at 5:20 pm

Avatar

[...] gesetzt sein und muss nicht zwingend im selben Verzeichnis wie htdocs und application sein.http://fritzthomas.com/php/zend-framework/33-how-to-teil-1-projektaufbau-konventionen-und-modulare-v…Help me!!I want to know how to become a software engineer?and also what …… concentrate on that [...]

8 | Zend Framework Tutorials Sammlung » Ullis Blog

March 3rd, 2009 at 10:07 am

Avatar

[...] Zend Framework How-To Teil 1: Projektaufbau, Konventionen und modulare Verzeichnisstruktur (Deutsch) Neue Tutorial Reihe des Entwicklers Fritz Thomas. Im ersten Teil dreht es sich um Projektaufbau, Konventionen und modulare Verzeichnisstruktur. http://fritzthomas.com/zend-framework/33-how-to-teil-1-projektaufbau-konventionen-und-modulare-verze... [...]

Comment Form


  • Rod: LOL not 6th... 4th... sorry.
  • Rod: May 6th... still waiting.... :(
  • Rod: April 27... i did not find anything about it at ExtJS.com :(
  • Fritz Thomas: You have to ask the guys at ExtJS.com actually. ;-)
  • Chris Thurrott: Good tutorial. Have you been able to make this work with multi-line text on a button? That is, some buttons have long labels that wrap and others ha
  • Green: Hi, take a look at this link: http://software-lgl.blogspot.com/2009/03/find-full-path-of-your-bash-script.html
  • Remeez: Is there anyway that we can have a beta version to play with in the meantime?
  • Zend Framework Tutorials Sammlung » Ullis Blog: [...] Zend Framework How-To Teil 1: Projektaufbau, Konventionen und modulare Verzeichnisstruktur (Deutsch) Neue Tutorial Reihe des Entwicklers Fritz T
  • vicox: Thx!
  • How to vertically align text and block elements | Overall | Fritz Thomas: [...] The important css declarations and attributes are “display: inline-block”, “vertical-align: middle” and “line-heig