Quicknavi |
|
PHP-Frameworks im Test (6)
3.4. Adventure-PHP-Framework
3.4.1. Allgemeines
Roadmap des Projekts
Das Adventure-PHP-Framework legt http://www.adventure-php-frame...te/Roadmap
die Roadmap für Releases bis Mitte 2008 fest. Darin werden die Features der Releases aufgeführt,
so dass der Entwickler ein Gefühl, für die kommenden Erweiterungen für seine Projekte
bekommt.
Aktualität der Version
Auf der Download-Seite des Projektes (http://www.adventure-php-frame.../Downloads)
steht eine Übersicht über die aktuell veröffentlichten Releases zur Verfügung.
Im Fall des aktuellen Testkandidaten sind dies das stable Release 1.3 und 1.4, wobei die aktuelle
Version eine zu PHP 5 kompatible Version ist.
Release-Packages in verschiedenen Formaten
Die Release-Packages liegen in der Form ZIP, TGZ und BZ2 vor. Die Dokumentation ist in separaten
Paketen und in unterschiedlichen Formaten (CHM, HTML+ZIP) erhältlich. Die zu einer Version
gehörigen Dokumentation kann auch online eingesehen werden.
CVS/SVN-Repositories
Für das Adventure-PHP-Framework steht kein CVS/SVN-Repository zur Verfügung. Bugfix-Releases
sind nur nach Anfrage per Kontaktformular verfügbar.
Bug-Tracking / Ticketing
Da das Projekt über keine Trac- oder JIRA-Installation verfügt wird Bug-Tracking und
Ticketing manuell über http://www.adventure-php-frame...ugtracking
abgewickelt. Das hat den Nachteil, dass die Diskussionen zu Bugreports nur verzögert online
einsehbar sind.
Version für PHP 4
Eine Version für PHP 4 ist erhältlich. Diese dient im aktuellen Release auch als
Haupt-Entwicklungs-Zweig (siehe Roadmap).
Version für PHP 5
Die installierte Version ist zu PHP 5 (im Test: Version 5.2.1) kompatibel.
3.4.2. Installation
Extract & Go
Der Einsteiger erhält auf der Download-Seite ein Package mit dem Namen adventure-demopack-*,
das alle relevanten Framework-Pakete und die komplette Webseite als Beispiel-Anwendung enthält.
Zur Installation muss dieses heruntergeladen und im DocumentRoot des Webservers oder einem VHOST
entpackt werden. Um das URL-Rewriting-Feature testen zu können sollte letztere Variante vorgezogen
werden. Um das URL-Rewriting zu deaktivieren, muss in der Datei
/apps/config/core/applicationmanager/INIT_demosite.ini
APPS__URL_REWRITING = false
gesetzt werden und die RewriteEngine des Apache Webservers mit
RewriteEngine Off
in der Datei /.htaccess abgeschaltet werden. Damit funktionieren Anwendungen auch
mit herkömmlichen URLs. Diese und weitere Hinweise finden sich in der Datei README.txt
des Demo-Packages. Das Paket adventure-codepack-* enthält bei jedem Release
den Code des Frameworks ohne die Beispiel-Applikation und kann für Updates oder andere
Installationen genutzt werden.
Konfiguration
Die mitgelieferten Beispiel-Applikationen müssen zunächst nicht konfiguriert werden und
sind ohne Zutun des Entwicklers lauffähig. Zum Betrieb des Demo-Gästebuch bzw. der Kommentar-
Funktion auf den Dokumentationsseiten sind die Hinweise in der Datei README.txt des
adventure-demopack-*-Releases zu beachten.
3.4.3. Erste Schritte
Demo-Software
Wie bereits unter 3.4.2 erwähnt stehen alle Applikationen als Demo-Applikationen zur Verfügung
und die Details zur Implementierung werden unter
http://www.adventure-php-frame...ktFormular und
http://www.adventure-php-frame...GaesteBuch näher erläutert.
Einführung / Quickstart
http://www.adventure-php-frame.../HalloWelt kann der Einsteiger als
erstes Beispiel für die Erstellung einer Applikation nutzen. Dort wird beschrieben, welche Schritte
notwendig sind um eine einfache Applikation mit dem Framework zu erstellt. Eine erweiterte Einführung
erhält der interessierte Anwender im Kapitel Grundlagen
(http://www.adventure-php-frame...Grundlagen).
Dort erfährt der Nutzer, wie welche Programm- bzw. Konfigurationsdateien eine Applikationen
benötigt. Weiterhin steht ein HOWTO zum Erstellen einer einfachen Webseite mit Hilfe des
Frameworks unter http://www.adventure-php-frame...eErstellen
zur Verfügung. Dieses kann als Grundlage für den Betrieb der mitgelieferten Beispiel-
Applikationen sowie zur Entwicklung weiterer Module genutzt werden.
3.4.4. Erstellung einer Webseite
Template-Bau / Layoutgestaltung
Dem Thema Templates ist in der Dokumentation ein eigenes Kapitel gewidmet. Auf
http://www.adventure-php-frame.../Templates werden die Grundlagen
des Template-Baus und die Möglichkeiten der Gestaltung von Templates erläutert. Die hier
vermittelte Struktur und die Funktion von Templates ist eine völlig andere, verglichen mit den
vorherigen Test-Kandidaten. Das Adventure-PHP-Framework verfolgt einen generischen GUI-Ansatz,
der dem Entwickler erlaubt, eine beliebig komplexe GUI-Struktur zu generieren. Wie auch im Kapitel
Klassen unter "DOM-Objektmodell der Präsentations-Schicht" geschrieben steht, wird die GUI über
einen Adventure-PHP-Framework-eigenes DOM abgebildet, auf das der Programmierer beliebig Einfluss
nehmen kann (http://www.adventure-php-frame...te/Klassen).
Das Einklinken weiterer Funktionen oder Module in die bereits vorhandene GUI wird damit stark
vereinfacht. Diese Tatsache unterstützt das komplett offene URL-Design, das keine starren
Strukturen wie
http://www.example.com/[{Module}/]{Controller}/{Action}[/{Param1}/../{ParamN}]
kennt, sondern frei gestaltet werden kann. Somit ist es möglich verschiedenste unabhängige
Module in einer GUI zu betreiben.
Die Test-Seite soll wie bei den bisherigen Probanden auch aus den Bereichen
- Menü
- Content
- Top-Menü
- News-Bereich
bestehen und die dafür bestimmten Inhalte tragen. Da Layouts im Adventure-PHP-Framework aus
mehreren Views bestehen können, die für sich genommen "kleine MVC-Einheiten" sind, kann
das Layout sehr einfach erstellt werden. Zunächst werden die dafür notwendigen Ordner
angelegt und ein neues Projekt erstellt:
Um das URL-Rewriting-Feature testen zu können,wurde im Ordner, in dem das Release-Package entpackt
wurde, ein neuer Ordner mit dem Namen testapp angelegt. In diesem wurde die index.php
und die .htaccess aus dem Demo-Projekt und die Struktur unter /frontend kopiert. Um
den neuen Ordner als DocumentRoot zu haben, musste die VHOST-Konfiguration um diese Änderung
angepasst werden. Das "Hallo Welt!"-Beispiel beschreibt nun, welche Schritte zum Anlegen einer neuen
Seite notwendig sind. Dazu muss zunächst die INIT-Datei INIT_testapp.ini unter
/apps/config/core/applicationmanager angelegt und eine Ordnerstruktur unter
/apps/sites/testapp (vgl. Demo-Projekt) erzeugt werden. Diese beinhaltet zunächst die
Ordner
sites/
testapp/
pres/
documentcontroller/
templates/
Der Ordner templates ist der Ablageort für Template-Dateien und wie oben beschrieben
werden fünf Template-Dateien darin angelegt, die die einzelnen Bereiche der Seite plus ein
"Master-Layout" beinhalten. Das sind:
- webseite.html: Master-Layout
- content.html: Content-Bereich
- topmenu.html: Bereich des oberen horizontalen Menüs
- news.html: News-Bereich in dem ein Banner eingeblendet wird
- menu.html: Inhalt des rechten vertikalen Menüs
Das Master-Template webseite.html wird mit dem HTML-Gerüst gefüllt, die übrigen
Dateien erhalten die jeweils relevanten Bereiche der Seite. Die einzelnen "Unter-Views" können
im Master-Layout nun mit dem XML-Tag <core:importdesign /> an den vorgesehenen
Stellen eingebunden werden. Da das Adventure-PHP-Framework die Dateien per Namespace adressiert - was
ein relativer Pfad zum APPS__PATH ist - müssen die Templates im Ordner
/apps/sites/testapp/pres/templates wie folgt in der Datei webseite.html adressiert
werden:
<core:importdesign namespace="sites::testapp::pres::templates" template="menu" />
Um die Webseite nun aufrufen zu können muss die index.php angepasst werden:
// Pfad zum Applikations-Verzeichnis angeben define('APPS__PATH','../apps'); define('APPS__NAME','testapp');
// ApplicationManager einbinden require_once(APPS__PATH.'/core/applicationmanager/ApplicationManager.php');
// Front-Controller einbinden import('core::frontcontroller','Frontcontroller');
// Frontcontroller erzeugen $fC = &Singleton::getInstance('Frontcontroller');
// Context und Sprache setzen $fC->set('Context','sites::testapp'); $fC->set('Language','de');
// Frontcontroller starten $fC->start('sites::testapp::pres::templates','website');
// Benchmark-Report ausgeben, falls benchmarkreport=true in der URL enthalten ist if(isset($_REQUEST['benchmarkreport'])){ if($_REQUEST['benchmarkreport'] == 'true'){ $T = &Singleton::getInstance('benchmarkTimer'); echo $T->createReport(); // end if } // end if }
Die gewünschte Webseite ist nun mit einem leeren Inhalts-Bereich zu sehen. Für die Füllung
des Inhaltsbereiches kann nun entweder die Template-Datei content.html gefüllt
werden, oder der auf http://www.adventure-php-frame...TagLibTags
beschriebe Tag <doc:createobject /> verwendet werden. Dieser sucht
in einem Ordner unterhalb des DocumentRoots - standardmäßig /frontend/content/ -
nach Content-Dateien der Form c_([a-z]{2})_([a-z0-9]{3,}).html, und ausliest deren
Inhalte aus und stellt sie dar. Im XML-Tag kann konfigurierten werden, welcher URL-Parameter verwendet
werden soll. In diesem Fall muss - um das geforderte URL-Layout einhalten zu können - der
Parameter Seite sein. Eine weitere Möglichkeit wäre es, für das
Template content.html einen DocumentController zu definieren, der den Inhalt aus einer
Datenbank liest. Um die Vergleichbarkeit mit den bisherigen Bewerbern zu gewährleisten
wurde im Template content.html der Quelltext
<core:addtaglib namespace="tools::html::taglib" prefix="doc" class="createobject" />
<document:createcontentobject requestparam="Seite" defaultvalue="Startseite" />
eingefügt. Der <core:addtaglib />-Aufruf muss hier deshalb platziert
werden, damit dem PageController mitgeteilt wird, dass eine weitere TagLibrary im aktuellen
Document verwendet wird. Ohne diese Bekanntgabe wird der Tag nicht ausgeführt. Um nun
Inhalte angezeigt zu bekommen müssen die hier verwendeten Dateien im Ordner /frontend/content
angelegt werden. Zum Test sind das c_de_startseite.html, c_de_benchmark.html
und c_de_klassen.html. Damit wurde die Basis der Test-Seite geschaffen und die
angelegten Seite können aufgerufen werden.
Handling von Controllern
Controller werden - wie bereits in "Template-Bau / Layoutgestaltung" angesprochen - nicht zentral
über einen Dispatcher gemäß den URL-Parametern aufgerufen, sondern auf Anforderung
innerhalb eines DOM-Knotens und mit den Informationen der URL, bzw. der Applikation, falls erforderlich.
Die Implementierung nach dem PageController- und Composite-Pattern sieht zudem vor, dass jeder
- wie es das Framework nennt - DocumentController vom abstrakten Controller baseController
erbt. Dieser besitzt die vom Framework zur Verfügung gestellten Möglichkeiten und unterstützt
den Anwender bei der Implementierung von Controllern.
Controller im Adventure-PHP-Framework werden im Template definiert. Damit kann der Entwickler selbst
entscheiden, ob er in einem Template (=DOM-Knoten) dynamische Inhalte erzeugen möchte oder nicht.
Möchte der Programmierer später dem Template einen Controller hinzugefügen, so kann dies
ohne Änderung der restlichen Applikation passieren. Die nötigen URL-Informationen kann sich
der Controller dabei aus der für ihn erweiterten URL ziehen.
Ein weiterer Unterschied zwischen den Kandidaten CakePHP, Codeigniter,
Zend Framework einerseits und dem Adventure-PHP-Framework andererseits, ist die Implementierung
des FrontControllers. Hier können - ähnlich wie die Controller für einen DOM-Knoten -
mehrere Actions in der URL platziert und ausgeführt werden. Damit ist der Anwender nicht darauf
beschränkt nur eine Applikation mit einem Controller und einer Action zu einer Zeit mit
Informationen bedienen zu können, sondern es können mehrere Applikationen, die gemeinsam in
einer GUI dargestellt werden, komplett unabhängig implementiert und ausgeführt werden. Dies
bringt den Vorteil mit sich, dass eine Gesamt-Applikation aus beliebig vielen Einzel-Applikationen
von unterschiedlichen Entwicklern und Teams zusammen "gesteckt" werden kann, solange sich diese
an die Paradigmen des Frameworks halten. Das in Kapitel 4.3.4., Abschnitt Erweiterbarkeit
der GUI-Komponenten, diskutierte Integrationsproblem von verschiedensten Teil-Applikationen in
eine ganze ohne Auflösung von Abhängigkeiten zu einer anderen Applikation in jeder der
Teil-Applikationen - siehe auch http://www.zfforum.de/showthread.php?t=685 -
ist damit auf einfache Art und Weise möglich. Die Implementierung von Actions für den
FrontController wird unter http://www.adventure-php-frame...controller
genauer beschrieben.
Erweiterbarkeit der GUI-Komponenten
Der PageController des Adventure-PHP-Frameworks kennt so genannte TagLibs. Diese sind
die Definition einer bestimmten Funktionalität, die hinter einem XML-Tag steckt. Viele der oben
verwendeten XML-TagLibs sind bereits im Framework integriert und können verwendet werden. Einige
von diesem müssen vor der Verwendung dem aktuellen Document zunächst bekannt gemacht
werden.
Da der integrierte TagLib-Parser beliebige TagLibs erkennen kann, können diese vom Entwickler
genutzt werden, um die Funktionalitäten des Frameworks und damit die einer Applikation oder
einer Webseite erweitert werden. http://www.adventure-php-frame...TagLibTags
beschreibt die bereits vorhandenen Libraries und http://www.adventure-php-frame...sErstellen
erörtert, wie neue TagLibs erstellt werden können. Nach Meinung des Autors verfügt
das Adventure-PHP-Framework damit über eine sehr komfortable Möglichkeit, die
Funktionalitäten des Frameworks und die Möglichkeiten einer GUI zu erweitern.
Für die Analyse wurde die unter http://www.adventure-php-frame...sErstellen,
Kapitel 3.1. Taglib php_taglib_hightlight beschriebene TagLib für das Highlighting
des PHP-Codes verwendet. Die Generierung des Menüs innerhalb der Dokumentationsseiten
wurde mit Hilfe der Klasse doku_taglib_navigation erzeugt. Der Quelltext der TagLib
gestaltet sich wie folgt (gekürzt):
class doku_taglib_navigation extends Document {
var $__DokuSites = array(); var $_LOCALS = array();
function doku_taglib_navigation(){
$this->_LOCALS = variablenHandler::registerLocal(array('Seite' => 'Startseite'));
[..]
// end function }
function transform(){
// Aktuelle Seite deklarieren $Page = $this->_LOCALS['Seite'];
// Vorherige Seite deklarieren $PreviousPage = $this->__getNeighborPageName($Page);
// Nächste Seite deklarieren $NextPage = $this->__getNeighborPageName($Page,'next');
// Rückgabe-Puffer deklarieren $Buffer = (string)'';
// Zurück-Blättern anzeigen $Buffer .= '<strong>«</strong>';
if($PreviousPage != null){ $Buffer .= '<a href="./?Seite='.$PreviousPage.'" title="Vorherige Seite">Vorherige Seite</a>';
// end if } else{ $Buffer .= '<font style="color: gray;">Vorherige Seite</font>';
// end else }
// übersicht anzeigen $Buffer .= ' | <a href="./?Seite=Startseite" title="Startseite">Startseite</a> | ';
// Nächste Seite anzeigen if($NextPage != null){ $Buffer .= '<a href="./?Seite='.$NextPage.'" title="Nächste Seite">Nächste Seite</a>';
// end if } else{ $Buffer .= '<font style="color: gray;">Nächste Seite</font>';
// end else }
$Buffer .= ' <strong>»</strong>';
// Puffer zurückgeben return $Buffer;
// end function }
function __getNeighborPageName($CurrentPage,$Type = 'previous'){ [..] }
// end class }
Um die TagLibrary in einem beliebigen Template einsetzen zu können muss diese zu Beginn mit
<core:addtaglib namespace="sites::testapp::pres::taglib" prefix="doku" class="navigation" />
eingebunden werden und kann anschließend mit
<doku:navigation />
verwendet werden.
Komplexe Layouts
Da die Komplexität des DOM-Objekt-Baums der Präsentationsschicht des Adventure-PHP-Frameworks
nicht beschränkt ist und die Funktionalität an beliebiger Stelle durch den Einsatz von
DocumentControllern, bzw. global betrachtet, von FrontController-Actions erweitert werden kann, ist
es ohne Weiteres auf einfache Weise möglich, komplexe Projekte zu realisieren. Insbesondere das
Entwickeln von Modulen fällt hier leicht, da diese einfach per XML-Tag konfiguriert dort
eingebunden werden können, wo sie benötigt werden. Am Beispiel des mitgelieferten
Gästebuchs wird das wie folgt vorgenommen:
<core:importdesign
namespace="modules::guestbook::pres::templates"
template="guestbook"
guestbookid="{ID}"
/>
Dabei konfiguriert der Parameter guestbookid die ID des an dieser Stelle auszugebenden
Gästebuchs. Vorteil dieses Verfahrens ist auch, dass eine Applikation - wie hier ein Gästebuch -
komplett unabhängig von der restlichen Webseite entwickelt und später eingebunden werden kann.
FormularDesign
Im Adventure-PHP-Framework ist ein Formular konsequenter Weise "auch nur" eine TagLib, die die Funktion
erweitert. Dazu findet der Entwickler im Ordner /apps/tools/form/taglib verschiedene
TagLibraries für jedes Formular-Element.
Jedes Formular wird durch Hinzufügen der Formular-TagLib plus der Definition des Formulars in
XML-Tags innerhalb eines Templates erzeugt. Im Gegensatz zu den bisherigen Frameworks muss der
HTML-/XML-Quellcode eines Formulars zwar von Hand geschrieben werden, jedoch können Funktionen
wie Formular-Validierung durch Definition dokumentierter Attribute aktiviert werden und es muss dazu
kein separater PHP-Code verfasst werden.
Auch in diesem Test soll ein Kontakt-Formular nach den Vorgaben der Bewertungs-Kriterien erstellt
werden. Dazu ist im vorliegenden Framework zunächst notwendig, dass ein neues Template und ein
Controller angelegt wird um das im Template definierte Formular auch darstellen zu können. Das
Template mit dem Namen kontakt.html wird im Ordner /apps/sites/testapp/pres/templates
abgelegt und beinhaltet folgenden Quellcode:
<@controller namespace="sites::testapp::pres::documentcontroller" file="kontakt_controller"
class="kontakt_controller" @>
<core:addtaglib namespace="tools::form::taglib" prefix="html" class="form" />
<h1>Kontaktformular</h1>
Wenn Sie mit mir in Kontakt treten möchten, dann benutzen Sie einfach dieses Formular. Geben Sie
Ihre Nachricht ein und schon kann es los gehen. Ich werden mich dann umgehend mit Ihnen in Verbindung
setzten. Bitte füllen Sie das Formular vollständig aus!
<html:placeholder name="Content" />
<html:form name="Formular" method="post" action="">
<span style="width: 47px; border: 0px solid black; margin-right: 24px;">Person / Gruppe:</span>
<form:select name="Person" class="eingabe_feld">
<select:option value="1">Max Müller</select:option>
<select:option value="2">Brigitte Hansen</select:option>
</form:select>
<br />
<br />
<span style="margin-right: 82px;">Name:</span><form:text name="Name" class="eingabe_feld"
style="width: 280px;" validate="true" button="Abschicken" />
<br />
<br />
<span style="margin-right: 37px;">eMail-Adresse:</span><form:text name="EMail" class="eingabe_feld"
style="width: 280px;" validate="true" validator="EMail" button="Abschicken" />
<br />
<br />
<span style="margin-right: 81px;">Betreff:</span><form:text name="Subject" class="eingabe_feld"
style="width: 280px;" validate="true" button="Abschicken" />
<br />
<br />
Kommentar:
<br />
<form:text name="Text" class="eingabe_feld" style="height: 200px; width: 400px; overflow: auto;"
validate="true" button="Abschicken" id="Comment" />
<br />
<br />
<form:button name="Abschicken" value="Abschicken" class="eingabe_feld" />
</html:form>
Im Controller muss nun - so geht es aus dem Beispiel aus
http://www.adventure-php-frame...ktFormular hervor -
das Formular transformiert und in einen Platzhalter eingesetzt werden. Dies passiert durch
class kontakt_controller extends baseController {
function transformContent(){ $Form = &$this->__getForm('Formular'); $this->setPlaceHolder('Content',$Form->transformForm()); // end function }
// end class }
in der Controller-Klasse kontakt_controller in der Datei
/apps/sites/testapp/pres/documentcontroller/kontakt_controller.php. Damit ist das
Formular bereits voll funktionsfähig. Features wir Validierung und Presetting werden bereits
out-of-the-box unterstützt und können per XML-Tag-Attributen konfiguriert werden.
Um das Formular abschicken zu können muss noch eine weitere Prüfung in den Controller eingebaut
werden. Um abzufragen, ob ein Formular abgesendet, bzw. korrekt ausgefüllt wurde hat das
Formular-Objekt zwei private Attribute, die mit get() ausgelesen und verarbeitet werden
können. Gemäß Beispiel muss der Controller damit wie folgt erweitert werden:
class kontakt_controller extends baseController {
function transformContent(){
$Form = &$this->__getForm('Formular');
if($Form->get('isSent') == true && $Form->get('isValid') == true){ header('Location: /Seite/Danke'); // end if }
$this->setPlaceHolder('Content',$Form->transformForm()); // end function }
// end class }
Innerhalb des if-Anweisungs-Blocks kann dann noch die Logik des E-Mail-Versandes ergänzt werden,
was hier nicht Teil der Prüfung war bzw. ist. Beim Versand des Formulars können die Werte
der Formular-Felder mit der Komponente variablenHandler ausgelesen werden. Dies
kann wie folgt passieren:
import('tools::variablen','variablenHandler');
class kontakt_controller extends baseController {
var $_FORM = array();
function kontakt_controller(){
$this->_FORM = variablenHandler::registerLocal( array( 'Name', 'Comment' ) );
// end function }
function transformContent(){
$Form = &$this->__getForm('Formular');
if($Form->get('isSent') == true && $Form->get('isValid') == true){
$Name = $this->_FORM['Name']; $Comment = $this->_FORM['Comment'];
[..]
// end if }
// end function }
// end class }
Um das Formular in die Seite einzubinden wurde unter /frontend/content eine neue
Datei mit dem Namen c_de_kontakt.html angelegt und mit der XML-Anweisung
<core:importdesign namespace="sites::testapp::pres::templates" template="kontakt" />
gefüllt. Bei Aufruf der URL
http://adventuretest.de/Seite/Kontakt
wird nun das Formular angezeigt. Legt man eine weitere Seite mit den Namen c_de_danke.html
an, so wird auch eine Danke-Meldung angezeigt.
3.4.5. URL-Handling
Unterstützung von URL-Rewriting
URL-Rewritung wird auch beim Adventure-PHP-Framework nativ unterstützt. Wie im Einstiegskapitel
angemerkt ist es jedoch ebenso möglich URL-Rewriting zu deaktivieren, da alle Anwendungen auch
ohne URL-Rewriting lauffähig sind, solange die dynamisch generierten Links mit dem
linkHandler oder dem frontcontrollerLinkHandler im FrontController-Betrieb generiert
werden. Um die Applikationen im URL-Rewriting-Modul ausliefern zu können bringt das
Adventure-PHP-Framework eine in der .htaccess-Datei befindliche RewriteRule der Form
RewriteEngine on
RewriteCond %{REQUEST_URI} !^(\/frontend) [NC]
RewriteRule !((index|helloworld).php|css|jpe?g|png|gif|zip|rar)$ \
/index.php?query=%{REQUEST_URI}&%{QUERY_STRING} [NC,L]
mit. Um das Feature nutzen zu können muss in der Apache-Konfiguration ein
AllowOverride All
für den aktuellen VHOST aktiviert, sein. Dies gilt insbesondere auch für die bisherigen
Test-Kandidaten.
Generik des URL-Layouts
Wie bereits in den vorherigen Kapiteln vorweg gegriffen, ist das URL-Layout des Adventure-PHP-Frameworks
an keine starren Regeln gebunden, sondern kann beliebig gestaltet werden. Im FrontController-Modus
werden dabei unterschiedliche Bereiche, in denen "normale" Parameter und FrontController-Actions
untergebracht werden durch das Zeichen "/~/" getrennt, vom frontcontrollerRewriteRequestFilter
im URL-RewriteModus oder vom frontcontrollerRequestFilter entsprechend ausgewertet und im
$_REQUEST-Array zur Verfügung gestellt. Im PageController-Betrieb übernimmt
die Rewriting-Aufgaben der pagecontrollerRewriteRequestFilter bzw. der standardRequestFilter
im Fall von deaktiviertem URL-Rewriting.
Ein weiteres Feature des URL-Handlings ist die Filter-Funktion, die alle HTML- und Tag-Zeichen codiert
um XSS-Angriffe zu vermeiden. Zudem werden alle Sonderzeichen in den Request-Werten mit Slashes versehen,
so dass diese - beispielsweise in Formular-Feldern - keine Zerstückelung der Inhalte erzeugen.
Für die Verwendung der Daten beispielsweise in Suchen müssen diese dann vom Programm wieder
decodiert werden.
URL-Manipulations-Tools / Linkgenerierung
Der Entwickler wird beim Adventure-PHP-Framework angehalten, die bereits mehrfach genannten Komponenten
linkHandler und frontcontrollerLinkHandler einzusetzen, wenn
es um Manipulation von URLs geht. Der frontcontrollerLinkHandler sollte dann eingesetzt werden,
wenn die Applikation mit dem FrontController ausgeführt wird, da dieser FrontController-Actions
in der URL beachtet. Grundsätzlich spricht jedoch nichts dagegen, immer den
frontcontrollerLinkHandler zu verwenden, da dieser "einfache" URLs ebenso beherrscht wie
FrontController-URLs.
Innerhalb der Evaluation wurden diese Komponenten wie folgt getestet:
import('tools::link','frontcontrollerLinkHandler');
$url = 'http://www.example.com:8180/Seite/Kontakt/perspektive/print'; $params = array( 'perspektive' => '', 'Seite' => 'Danke', 'TestParam' => 'TestParamValue' ); echo frontcontrollerLinkHandler::generateLink($url,$params);
Ausgabe:
http://www.example.com:8180/Seite/Danke/TestParam/TestParamValue
Es können sowohl bestehende Parameter geändert, als auch bestehende gelöscht oder neue
hinzugefügt werden. Ähnlich verhält sich der frontcontrollerLinkHandler, wenn
FrontController-Actions im Spiel sind. Diese werden wie "normale" Parameter in die URL eingefügt.
Geprüft wurde hier zudem, dass Ampersands in Links automatisch codiert werden.
3.4.6. Design des Frameworks
Umfang der mitgelieferten Komponenten
Das Release-Package des aktuellen Test-Kandidaten umfasst im Vergleich zu den bisherigen Frameworks
etwas weniger Module, was auch an der Strukturierung dieser gelegen sein kann. Das Adventure-PHP-Framework
liefert im aktuellen Release
- die Grundkomponenten des Frameworks,
- eine Demo-Seite mit vielen Beispielen
- fertige Module wie Pager, Gästebuch, Kontaktformular und
- eine Reihe von Tools
zur Unterstützung der Arbeit mit. Was das Thema Module angeht, so sind im Adventure-PHP-Framework
mehr fertige Applikationen (Module) enthalten als in den bisherigen Probanden. Die genannten Module
sind dabei schon recht mächtige Applikationen, wie unter
http://www.adventure-php-frame...ite/Module beschrieben ist. Der Pager
ist dabei ein sehr treffendes Beispiel für eine Business-Komponente, die die komplette Aufgabe
des Pagings von Datenbank-Ergebnissen übernehmen kann.
Besonders zu erwähnen ist die Benchmark-Komponente, da diese bereits sehr tief im Code verwoben
ist und ohne Zutun des Programmierers zu allen wichtigen Teilen der Software Benchmarks erstellen
kann. Eine weitere herausragende Komponente ist die Implementierung des PageControllers, die ein
sehr generisches Design der GUI-Komponenten der Applikation zulässt. Erwähnenswert sind
in diesem Zusammenhang die mitgelieferten TagLibs. Diese bilden bereits 75% der Anwendungsfälle
ab und können out-of-the-box konfiguriert und eingesetzt werden. Weitere Beschreibungen finden
sich unter http://www.adventure-php-frame...enreferenz,
bzw. in den entsprechenden Kapiteln der Dokumentation.
Einsatz von Design-Pattern
Design-Pattern spielen auch beim Adventure-PHP-Framework eine herausragende Rolle. Nicht nur, dass
das Framework nach anerkannten Design-Pattern entwickelt wurde (siehe hierzu
http://www.adventure-php-frame...Grundlagen), sondern es bietet
auch die Grundlagen und Tools um nach oft verwendeten Design-Pattern (vgl. MVC) entwickeln zu können.
Unter Hilfsmittel fallen dabei eine "abstract singleton"-Implementierung, die Anwendung des
Fabric-Entwurfsmusters und Weiterer. Da das Framework keine native PHP 5 Version bietet, sind Konstrukte
wie Interfaces oder abstrakte Klassen nicht im Quellcode enthalten, jedoch durch das Klassendesign
fest verwoben.
Struktur des Quellcodes / Design der Klassen
Die im Framework enthaltenen Klassen erben alle von einer gemeinsamen Basis-Klasse, die die
grundlegenden Interface-Methoden und -Attribute bereits mitbringt. So kann der Entwickler immer davon
ausgehen, dass ein von coreObject erbendes Objekt eine abstrakte get()- und
set()-Methode hat, um private Attribute manipulieren zu können. Des weiteren führt
die Klasse coreObject das Namespace-Handling und das initialisieren einer Klasse ein, das
in Applikationen häufig für Business- und Daten-Schicht-Komponenten zum Einsatz kommt.
Inkonzequenz kann den Entwicklern im Bereich der Klassenbenennung vorgeworfen werden, da hier eine
Mixtur aus CamelCase- bzw. "Alles klein"-Schreibweise je nach Bestimmung der Klasse propagiert wird.
Die Struktur des Quellcodes ist per-se ist mit gut zu bewerten, da für jedes Package eine Struktur
im Ordner-Baum angelegt wurde, bzw. der Quell-Code der mitgelieferten Komponenten sehr gradlinig und
konsequent aufgebaut ist, was den Blick in den Quellcode - falls notwendig - erleichtert.
Einsetzbarkeit für mehrere Applikationen
Das Adventure-PHP-Framework bringt mit der Namespace- und Context-Behandlung ein sehr mächtiges
Werkzeug mit um Applikationen, die den Design-Richtlinien des Frameworks genügen, in vielen
verschiedenen Applikationen und Umfeldern einsetzen zu können. Die Konfigurations-Direktive
APPS__ENVIRONMENT bestimmt bereits in der Basis-Konfigurationsdatei in welchem Umfeld die
Applikation ausgeführt wird. Um eine Applikation leichter auf ein anderes System portieren zu
können, ist es dabei lediglich notwendig dafür einen Satz von Konfigurationsdateien anzulegen
und die Direktive auf einen anderen Wert zu setzen.
Des Weiteren erhält jede Applikation einen Namespace (=Ablage-Ort der Programm- oder Modul-Dateien)
und einen Kontext, der über die Applikation (=Webseite) gesteuert wird. Diese drei
Unterscheidungsmerkmale helfen dem Entwickler universell wiederverwendbare Applikationen und Module
zu verfassen. Etwas gewöhnungsbedürftig ist dabei jedoch die Benennung der
Konfigurationsdateien, da diese sowohl unter dem richtigen Namespace und der richtigen Kontext-Struktur
abgelegt und mit dem für das Umfeld richtigen Dateinamen benannt sein müssen. Eine Beschreibung
hierzu liefert http://www.adventure-php-frame...figuration. Die
Fehler-Meldungen des ConfigurationManager's sind dabei jedoch sehr ausführlich abgefasst
und bieten Hinweise auf das Problem.
Erweiterbarkeit
Interessierte Programmierer können das Framework beliebig erweitern, da eine sehr generische
Grund-Struktur vorhanden ist. Besonders im GUI-Bereich ist es möglich beliebige Erweiterungen
zu implementieren um die Ausgabe eines Projektes nach dem Geschmack des jeweiligen Entwicklers zu
gestalten. Aber nicht nur in der Präsentationsschicht, auch in den übrigen Bereichen ist
es mit dem Design des Adventure-PHP-Frameworks ohne Probleme möglich Erweiterungen zu verfassen.
Scaffolding
Ein Rapid Development Feature im Sinne von CakePHP und CodeIgniter ist nicht enthalten und laut Roadmap
bis jetzt nicht vorgesehen. Für den Zugriff auf Datenbanken ist zwar eine generische Komponente
(leider nur für MySQL) vorhanden, Pattern wie Table-Data-Gateway oder Row-Data-Gateway sind nicht
implementiert. Aus Sicht des Autors ist dieses - wie auch beim Zend Framework - nicht Teil der
aktuellen Strategie. Diese Komponenten können bei Bedarf jedoch einfach als Module hinzugefügt
werden.
3.4.7. Dokumentation
Dokumentation des Quellcodes
Der Quellcode des Frameworks ist sehr gut dokumentiert. Einziger Nachteil ist, dass die Dokumentation
nur in deutscher Sprache vorhanden ist.
API-Dokumentation
Die API-Dokumentation des Frameworks ist jeweils abhängig von der Version unter
http://www.adventure-php-frame.../Downloads verfügbar.
Einführungen, Tutorials und Anwendungs-Beispiele
Leider verfügt das Adventure-PHP-Framework nicht über ein Wiki in das verschiedene
Entwickler ihre Erfahrungen und Code-Snippets posten können. Die übrigen Anwendungsbeispiele
verraten jedoch sehr viel über die Verwendung und die Anwendung des Frameworks. Einsteiger erhalten
mit dem Webseiten-Tutorial unter http://www.adventure-php-frame...eErstellen
einen einfachen Einstieg in den Webseitenbau. Angenehm fällt auf, dass die Anwendungsbeispiele
immer einen Bezug zur Praxis aufweisen.
ChangeLogs / Migrations-Hinweise für API-ChangeLogs / Migrations-Hinweise für API-ÄnderungenAuml;nderungen
Ein einfaches ChangeLog ist in den Release-Notes eingearbeitet, ein erweitertes gibt es unter
http://www.adventure-php-frame.../ChangeLog.
3.4.8. Support
Da das Adventure-PHP-Framework nicht den kommerziellen Hintergund wie die bisherien Test-Kandidaten
aufweist, ist der Support nicht so "exzellent" aufgestellt und es ist kein "Enterprise-Bezahl-Support"
möglich. Hinter dem Framework steckt ein OpenSource-Projekt ohne hauptamtliche Entwickler. Support
erhält der Anwender daher nur auf der Seite selbst, durch das Manual und die API-Dokumentation,
per Kontakt-Formular und im PHPFriend.de-Forum unter http://www.phpfriend.de/forum.
Charmant ist es jedoch, dass man mit Hilfe des Kontakt-Formulars und einem Post im Forum direkten
Zugriff auf die Entwicklung hat. Zum aktuellen Zeitpunkt ist zudem noch kein WIKI verfügbar, in
dem Benutzer Tipps und Tricks oder Ihre Erfahrungen veröffentlichen können. Alternativ dazu
befindet sich am Ende jeder Dokumentationsseiten eine Kommentarfunktion, die als solches Instrument
genutzt werden kann.
3.4.9. Benchmark
Das Benchmark-Ergebnis ist im Vergleich zu den übrigen Test-Kandidaten hervorragend gut.
Während der bisherige Favorit CakePHP die Benchmark-Seite in 0.1134 s gerendert
hat benötigt das Adventure-PHP-Framework trotz komplexerer GUI-Engine nur etwas mehr als ein Drittel
und kommt auf eine durchschnittliche Zeit von 0.0428 s. Zur Messung wurde auch
hier der im Framework integrierte benchmarkTimer verwendet und die Benachmark-Seite
mit
http://adventuretest.de/Seite/Benchmark/benchmarkreport/true
aufgerufen.
» Weiter auf Seite 7 (Zusammenfassung).
Kommentare
Möchten Sie den Artikel eine Anmerkung hinzufügen, oder haben Sie ergänzende Hinweise? Dann können Sie diese hier einfügen. Die bereits verfassten Anmerkungen und Kommentare finden Sie in der untenstehenden Liste.
Für diesen Artikel liegen aktuell keine Kommentare vor.
|