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
  • Fark
  • Google Bookmarks
  • Facebook
  • MisterWong.DE
  • Twitter
  • Twitthis
  • Yahoo! Bookmarks
  • Yigg

11 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... [...]

9 | Christoph

July 21st, 2009 at 2:57 pm

Avatar

In den Codeteilen scheint das Escaping nicht korrekt zu funktionieren. Ich sehe leider statt des Kleinerzeichens den HTML-Code.

10 | iptoux

December 9th, 2009 at 9:11 pm

Avatar

darf man fragen ob da noch nen weiterer teil kommt ? ich mein ist ja jetzt bald 2 jahre her seit dem ersten teil.

11 | admin

December 23rd, 2009 at 8:13 am

Avatar

Kurz nachdem ich mein Tutorial geschrieben habe hat sich einiges im Zend Framework geändert bzw. wurde in die Coding Standards aufgenommen. Deshalb ist auch vieles nicht mehr wahr oder funktioniert nun anders und ein weiterer Teil der auf den ersten aufbaut wäre nicht mehr richtig.
Ich entschuldige mich bei allen die seit 2 Jahren darauf warten!

Comment Form


  • admin: Hi! For more information go to http://extjs.com/ . There is a preview video of this Tool called Ext.De
  • jagocoding: nice info bro... where can i download this tools ?? can u give me ulr, this is free or not ?
  • admin: Of course! This should be rm -rf /tmp/*
  • Christian: rm -rf /tmp* bad idea. at least do rm -rf /tmp/* but if things go worse it will skrew your X Session
  • Aleksandr: Hi! Thank you, it really works, you could even do it in one line like here: http://www.devhands.com/2010/01/how-to-get-the-full-path-from-the-running
  • matt: thanks for the tip. freeing up the distfiles freed me up 5GB of diskspace. My root is only 20GB which I thought should be plenty but my disk hit 100
  • admin: Kurz nachdem ich mein Tutorial geschrieben habe hat sich einiges im Zend Framework geändert bzw. wurde in die Coding Standards aufgenommen. Deshalb i
  • DarthMaul: Thank you. You seem to be the only one who could answer this for me. Everyone else seems to recommend using $PWD or pwd command and just won't listen
  • Jochen: Der Fehler kann _auch_ auftreten, wenn an den Dateien das Lese-Recht für den Webserver fehlt.
  • iptoux: darf man fragen ob da noch nen weiterer teil kommt ? ich mein ist ja jetzt bald 2 jahre her seit dem ersten teil.