Apr 19 2011

Mehrere Zend Cycle Helper im Einsatz

Falls ihr euch schon mit dem Cycle Helper von Zend beschäftigt habt, werdet ihr irgendwann an den Punkt kommen, wo ihr mehrere “cycles” in einer Ausgabeseite verwenden möchtet. Dazu sieht der Helper vor, dass man Namen für jeden Cycle vergibt. Wählt man diese nicht, wird der default Name verwendet. Dies kann wiederum zu nervigen Seiteneffekten führen. Hierzu ein kleines Beispiel:

Sieht auf den ersten Blick nicht unbedingt falsch aus. An dieser Stelle sollte man jedoch wissen, dass der zweite next() Aufruf problematisch ist. Um das Problem zu lösen verwendet man Namen für jeden Cycle, in etwa so:

Was mir neulich auch noch passiert ist, ist eine falsche Ausgabe des Ergebnisses. Bei einem echo auf den cycle()->next() Aufruf wird automatisch die toString() Methode des Helpers aufgerufen. Möchte man nun mit Variablen arbeiten, wird es auch hier leicht verwirrend, wenn man dies nicht im Hinterkopf behält. Dazu auch ein kleines Beispiel:

// Hiermit erhalten wir lediglich das helper Objekt
$output = $this->Cycle(array('blue', 'red'))->next();

// Eigentlich möchten wir aber dies hier
$output = $this->Cycle(array('blue', 'red'))->next()->toString();

// Ausgabe im Verbund funktioniert beim ersten Beispiel nicht...
echo 'Text' . $output;

// Bei einem direkten echo alledings schon
echo $output;

Ich wünsche viel Spaß beim Ausprobieren und viel Erfolg bei der Entwicklung neuer SuperApplikationen ;)


Apr 3 2011

Module im Zend Framework

Da ich nun auch mit Module rumgespielt habe, ist mir ein recht seltsames Verhalten aufgefallen. Man definiert ein Hauptmodul, was man als default oder core bezeichnen kann. Zudem kann man auch ein Modulverzeichnis angeben und sogar die Ordnernamen für darunter liegende Controller definieren. Soweit so gut, hört sich doch nicht schlecht an.

Die oben genannten Schritte erledigt man z.B. so:

$frontController = Zend_Controller_Front::getInstance();
$frontController->setDefaultModule('core');

$frontController->setModuleControllerDirectoryName('controllers');
$frontController->addModuleDirectory(APPLICATION_PATH . '/modules');

Interessanterweise ist es nun so, dass man irgendwann, wenn man einen Controller außerhalb des core-Moduls (in dem obigen Beispiel) aufruft, erhalt man eine Meldung, die dann z.B. sowas hier enthält:

Message: Invalid controller class (“Mymodule_IndexController”)

Bei Zend ist es ein wenig tricky. Man muss bei zusätzlichen Modulen den Modulnamen vor den Controller-Namen schreiben. Der Dateiname des Controllers bleibt davon allerdings verschont. Klingt irgendwie seltsam, ist aber so.

In der Praxis sieht das nun so aus, in der Datei IndexController.php schreiben wir einfach:

class Mymodule_IndexController extends Zend_Controller_Action
{

}

Schon funktioniert alles wie man es haben möchte. Ich wünsche viel Spaß und Erfolg ;)


Mrz 3 2010

Ubuntu für das Zend Framework konfigurieren

Aus aktuellem Anlass – einer Neuinstallation meines Systems – möchte ich euch die Schritte erklären, die zu einer lokalen LAMP (Linux Apache MySQL und PHP) Entwicklungsumgebung für Zend-Framework Projekte unter Ubuntu 9.10 Karmic Koala führen.

Ein fertiges Linux-System solltet ihr mit Ubuntu ja bereits besitzen. D.h. den nächsten Schritt, den man gehen muss, ist den Apache-Server zu installieren. Unter Ubuntu bewerkstelligt man dies in der Console mit dem einfachen Aufruf

sudo apt-get install apache2

Eine Internetverbindung vorausgesetzt, solltet ihr nun die Download-, Installations- und Konfigurationsroutine sehen. Um zu überprüfen, ob der Apache nach der Installation läuft, öffnet einen Browser eurer Wahl und versucht die Adresse http://127.0.1.1 aus. Ihr solltet etwas in der Art “It Works” zu lesen erhalten.

Das Zend-Framework basiert ja bekanntlich auf PHP und so benötigen wie jetzt entsprechend PHP. Um PHP5 zu installieren, bemüht man widerum die Console und holt die aktuelle Version aus den Quellen:

sudo apt-get install php5

Nach erfolgreicher Installation sollte der Apache neu starten und wir können überprüfen, ob die Installation korrekt ausgeführt wurde. Dazu wechselt man in das Web-Verzeichnis des Servers:

cd /var/www

Hier sollte bereits eine index.html existieren, die wir schon im Web-Browser bewundern durften. Mit dem Aufruf…

sudo gedit phpinfo.php

… erstellt man die Datei phpinfo.php und öffnet diese gleichzeitig mit dem (in Ubuntu mitgelieferten) Editor, welcher übrigens um einges mächtiger ist, als z.B. Notepad unter Windows, da er für sehr viele Dateitypen Syntax-Highlighting unterstützt. In diese Datei fügt ihr nun folgende Zeile ein und speichert die Datei ab:

<?php phpinfo(); ?>

Damit haben wir eine Test-PHP-Datei erstellt, welche die Methode phpinfo aufruft und uns somit ausführliche Informationen über die installierte PHP-Version liefert. Diese Datei könnt ihr über den Web-Browser unter http://127.0.1.1/phpinfo.php aufrufen. Bei erfolgreicher PHP-Installation solltet ihr nun PHP-Informationen (z.B. die Version) sehen.

Einen großen Teil habt ihr damit schon geschafft und könntet schon fast mit einem Zend-Projekt anfangen. Was noch fehlt ist die Datenbank und das Apache ModRewrite Modul. Wofür die Datenbank (MySQL) gebraucht wird, sollte klar sein. Das Modul benötigen wir, um euer Projekt zu “privatisieren”. Das bedeutet, dass wir – gemäß ZF-Vorgabe – einzig und allein einen öffentlichen Zugriff auf die index.php anbieten.

Starten wir doch mit dem Einfacheren, dem Modul. Dieses ist nämlich schon installiert und muss nur noch aktiviert werden. Dazu wieder die Konsole:

sudo a2enmod rewrite

Kurze Erklärung dazu: a2 (Apache2, unser Server) en (enable, aktivieren) mod (Modul) rewrite. Eventuell – falls nicht automatisch durchgeführt – müsst ihr den Apache neu starten.

Nun möchten wir uns noch um die letzte Komponente, einen MySQL-Server kümmern. Dazu bemühen wir wieder die geliebte Konsole und holen uns den mysql-server mit Hilfe von apt:

sudo apt-get install mysql-server

Bei der Installation solltet ihr die entsprechenden Zugriffspasswörter wählen, der Rest passiert automatisch. Für diejenigen, die phpMyAdmin kennen und nutzen möchten, bietet sich an das Paket phpmyadmin zu installieren, welches dann unter http://127.0.1.1/phpmyadmin zu finden ist.

sudo apt-get install phpmyadmin

Mit dieser Konfiguration könnt ihr euch nun in aller Ruhe in ein neues Zend-Projekt stürzen. Falls ihr möchtet, könnt ihr auch entsprechende Tipps und Tutorials dazu in meinem kleinen ScienceBlog zur Hilfe nehmen.


Feb 3 2010

MVC-Pattern im Web

Das MVC-Pattern gibt es schon seit dem 20. Jahrhundert. Publiziert wurde es in den 90er Jahren zusammen mit dem Buch “Design Patterns” u.a. von Erich Gamma. Damals bezog sich das Pattern noch auf GUI-basierte Programme, z.B. ein Texteditor.

Mit der Verbreitung des Web wurde dieses Pattern auch auf die Webwelt portiert. Obwohl das Pattern schon so lange bekannt ist, trifft man in der Entwicklerwelt trotzdem oft auf Menschen, denen das Muster nichts sagt. Mit diesem Beitrag möchte ich das Pattern aufarbeiten, um es in späteren Beiträgen (z.B. für das Zend Framework) als Grundlage gebrauchen zu können.

Um das Pattern zu verstehen, ist es am besten vorher zu erfahren, was die Abkürzung bedeutet. Das M steht für das Model, V für den View und das C für den Controller. Die Langversion lautet also Model-View-Controller Pattern. Nachfolgend werde ich die einzelnen Ebenen und deren Zusammenspiel erläutern.

Das Model
In allen drei Schichten muss man im Grunde etwas weiter ausholen, so auch beim Model. Das Model dient allgemein dazu die reale Welt – genauer gesagt Teile davon – in einer gewissen Form abzubilden. In der Softwareentwicklung wird dafür ein oder mehrere Diagramme des Problembereichs erstellt. Diese Diagramme dienen später als Plan, um die Objekte bzw. Datenstrukturen zu erstellen.

Diese Daten und ihre Strukturierung stellen das Model dar. Man könnte diese Ebene vereinfacht auch als Datenbehälter bezeichnen. Nehmen wir doch einfach ein konkretes Beispiel. Ich möchte mein Auto modellieren. Mich interessieren dabei die Marke, die PS Angabe und die Höchstgeschwindigkeit. Dazu erstelle ich eine Klasse “Auto” mit den Klassen-Attributen “marke”, “ps” und “maximalgeschwindigkeit”. Das Model ist nun fast fertig. Das einzige, was es noch benötigt sind sogenannte Getter- und Setter-Methoden. Diese brauchen wir, um einem Objekt der Klasse Auto Daten hinzufügen zu können und ebenfalls diese Daten wieder auszulesen.

Der View
Der View ist mitunter am einfachsten zu erklären. Er stellt die Sicht auf das Model dar. D.h. die Daten des Models werden hier auf dem Bildschirm visualisiert. In der Web-Welt ist es die (ausgelieferte) Webseite, die der Benutzer am Ende zu sehen bekommt. Zusätzlich ist der View die Schnittstelle zwischen System und Benutzer. Der Benutzer interagiert also auf der View-Ebene, z.B. durch Formulare oder durch das Klicken eines Links.

Der Controller
Der Controller ist als Steuerungseinheit zu verstehen. Der Idee nach wissen Model und View am Anfang nichts voneinander. Die Anfrage eines Clients (Web-Browser des Benutzers) an einen Server wird vom Controller entgegen genommen. Dieser Wertet die Anfrage aus.

Nehmen wir nochmals das Beispiel aus dem Model-Abschnitt. Der Benutzer möchte nun erfahren, welches Auto ich fahre und klickt entsprechend auf einen Link. Der Controller erkennt nun diese Anfrage und bereitet das Model auf. Dazu erstellt er ein Auto-Objekt und setzt die Daten auf “Suzuki”, “92″ und “180km/h”. Das Model ist damit gefüllt. Jetzt entscheidet der Controller noch, dass die Seite für das Auto angezeigt werden soll, das ist der View.

Würde die Seite jetzt ausgeliefert werden, wäre leider nichts sichtbar, da der View ja nach wie vor nichts vom Model weiß. Auch dies erledigt der Controller. Verinfacht gesagt teilt er dem View mit “Benutzer bitte dieses Auto-Objekt zum Anzeigen”.

Dadurch, dass der View nun das Auto-Objekt kennt, kann er über die Getter-Methoden des Models auf die Daten zugreifen.

Einige Grundsätze fehlen bei dieser recht einfachen Beschreibung des MVC-Pattern:

  1. Der View manipuliert keine Daten des Models
  2. Das Model ist das ahnungsloseste der drei Ebenen und darf nicht mit sicht auf den View oder den Controller entwickelt werden
  3. Der Controller füllt in den meisten Fällen nicht die Daten des Models, sondern veranlasst das Laden aus der Datenbank (Stichwort Data-Access-Objects)