<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Christian Renner</title>
	<atom:link href="http://christian-renner.eu/feed/" rel="self" type="application/rss+xml" />
	<link>http://christian-renner.eu</link>
	<description>Christian Renner - Informationen zur Person, Referenzen und Blog.</description>
	<lastBuildDate>Thu, 22 Dec 2011 14:21:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	
		<item>
		<title>Große MySQL-Dumps zeilenweise splitten und importieren</title>
		<link>http://christian-renner.eu/development/grosse-mysql-dumps-zeilenweise-splitten-und-importieren/</link>
		<comments>http://christian-renner.eu/development/grosse-mysql-dumps-zeilenweise-splitten-und-importieren/#comments</comments>
		<pubDate>Mon, 09 Aug 2010 11:00:34 +0000</pubDate>
		<dc:creator>Renner</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[Datenbanken]]></category>
		<category><![CDATA[Linux]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.christian-renner.eu/?p=481</guid>
		<description><![CDATA[Dieser Post soll darstellen, wie man einen MySQL-Dump zeilenweise splittet bzw. nur bestimmte Teile extrahiert, um nur Teile der Datenbank weiderherzustellen bzw. den Import zeitlich aufzuteilen. Er ist vor allem für mich als Gedankenstütze gedacht, könnte aber auch für andere interessant sein. Erstellt man mittels mysqldump ein Backup der Datenbank, verwendet man wohl so was [...]]]></description>
			<content:encoded><![CDATA[<p>Dieser Post soll darstellen, wie man einen MySQL-Dump zeilenweise splittet bzw. nur bestimmte Teile extrahiert, um nur Teile der Datenbank weiderherzustellen bzw. den Import zeitlich aufzuteilen. Er ist vor allem für mich als Gedankenstütze gedacht, könnte aber auch für andere interessant sein.</p>
<p>Erstellt man mittels <a href="http://dev.mysql.com/doc/refman/5.1/de/mysqldump.html">mysqldump</a> ein Backup der Datenbank, verwendet man wohl so was ähnliches, wie folgt:</p>
<pre class="c">
mysqldump -h HOST -u USER DBNAME -p > FILENAME.sql
</pre>
<p>Als Ergebnis erhält man ein MySQL-Skript, mit welchem man mittels <a href="http://dev.mysql.com/doc/refman/5.1/de/mysql.html">mysql</a> die komplette Datenbank wieder herstellen kann und zwar wie folgt:</p>
<pre class="c">
mysql -h HOST -u USER DBNAME -p < FILENAME.sql
</pre>
<h2>Import zerlegt</h2>
<p>So weit - so gut. Das dürfte für die Meisten nichts Neues sein. Handelt es sich nun jedoch bei FILENAME.sql um einen recht großen Dump, muss man diesen eventuell mit <a href="http://www.manpagez.com/man/1/split/">split</a> zerlegen. Das könnte man zum Beispiel mit einem der folgenden Anweisungen erledigen:<br />
<span id="more-481"></span></p>
<pre class="c" name="code">
#Erzeugt Dateien mit jeweils 1000 Zeilen Länge
split -l 1000 FILENAME.sql
#Erzeugt Dateien mit jeweils 1 MB Größe
split -b 1M FILENAME.sql
</pre>
<h2>Import nach Maß</h2>
<p>Um nun nur eine bestimmte Tabelle des Dumps zu importieren, macht man sich die Struktur des dump-Files zu eigen. Dieses liegt in der folgenden wiederkehrenden Form vor:</p>
<ul>
<li>Tabellenkommentar</li>
<li>CREATE TABLE - Anweisung</li>
<li>Zeilenkommentar</li>
<li>INSERT - Anweisungen</li>
</ul>
<p>Jeder Tabellenkommentar sieht wie folgt aus:</p>
<pre class="c" name="code">
--
-- Table structure for table `TABELLENNAME`
--
</pre>
<p>Nun kann man sich von <a href="http://www.manpagez.com/man/1/grep/">grep</a> die Zeilennummern ausgeben lassen, in denen "Table structure for table" steht:</p>
<pre class="c" name="code">
grep -n 'Table structure for table' FILENAME.sql
# Ergibt folgende Ausgabe:
# 19:-- Table structure for table `table1`
# 44:-- Table structure for table `table2`
# 447:-- Table structure for table `table3`
# 544:-- Table structure for table `table4`
# 625:-- Table structure for table `table5`
</pre>
<p>Die letzte Zeile einer Tabellensequenz, heißt bei mir immer "UNLOCK TABLES;". Somit können wir die Länge der letzten Tabelle bestimmen:</p>
<pre class="c" name="code">
grep -n 'UNLOCK TABLES;' FILENAME.sql
# Ergibt folgende Ausgabe:
# 41:UNLOCK TABLES;
# 444:UNLOCK TABLES;
# 541:UNLOCK TABLES;
# 622:UNLOCK TABLES;
# 674:UNLOCK TABLES;
</pre>
<p>Die Nummer der letzten Zeile bekommt man mit:</p>
<pre class="c" name="code">
grep -n 'Dump completed' FILENAME.sql
# Ergibt folgende Ausgabe:
# 686:Dump completed
</pre>
<p>Möchte man nur bestimmte Zeilennummern des Dumps importieren, kann man diesen mit <a href="http://www.manpagez.com/man/1/sed/">sed</a> erstellen:</p>
<pre class="c" name="code">
#Erzeugt eine Datei mit den Zeilen 43 bis 445 des Dumps (table3):
sed -n '43,445 p' < FILENAME.sql > FILENAME_part.sql
</pre>
<p>Zu beachten gilt:<br />
Am Anfang der FILENAME.sql befinden sich Anweisungen, die die Datenbankverbindung für den Import konfigurieren. Unter Anderem wird hier die Zeichenkodierung der Verbindung gesetzt. Am Ende des Datenbankskriptes (nach der letzten Tabellensequenz) werden diese Parameter wieder zurückgesetzt.</p>
<p>Im Folgenden wollen wir sowohl den Header als auch den Footer an den Tabellendump kleben:</p>
<pre class="c" name="code">
# Header extrahieren:
sed -n '1,17 p' < FILENAME.sql > header.sql
# Tabelle (table3) extrahieren:
sed -n '43,445 p' < FILENAME.sql > FILENAME_part.sql
# Footer extrahieren:
sed -n '675,686 p' < FILENAME.sql > footer.sql
# Zusammenführen der Dateien:
cat header.sql FILENAME_part.sql footer.sql > table3.sql
# Import:
mysql -h HOST -u USER DBNAME -p < table3.sql
</pre>
]]></content:encoded>
			<wfw:commentRss>http://christian-renner.eu/development/grosse-mysql-dumps-zeilenweise-splitten-und-importieren/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>PHPUnit in PDT integrieren unter MacOSX 10.6</title>
		<link>http://christian-renner.eu/development/phpunit-in-pdt-integrieren-unter-macosx-10-6/</link>
		<comments>http://christian-renner.eu/development/phpunit-in-pdt-integrieren-unter-macosx-10-6/#comments</comments>
		<pubDate>Sat, 17 Jul 2010 11:58:57 +0000</pubDate>
		<dc:creator>Renner</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Continuous Integration]]></category>
		<category><![CDATA[Eclipse]]></category>
		<category><![CDATA[MacOSX]]></category>
		<category><![CDATA[PDT]]></category>
		<category><![CDATA[PEAR]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHPUnderControl]]></category>
		<category><![CDATA[PHPUnit]]></category>
		<category><![CDATA[Xampp]]></category>

		<guid isPermaLink="false">http://blog.christian-renner.eu/?p=446</guid>
		<description><![CDATA[Um Unittests und ggf. weitere Checks direkt aus der IDE zur Ausführung zu bringen, bietet es sich an, diese Funktionalität in die jeweilige Entwicklungsumgebung einzubetten. Meine Systemvoraussetzungen: MacOSX 10.6.4 PDT 1.2 XAMPP für Mac OSX Um PHPUnit zu installieren, wird das PEAR-Framework vorausgesetzt. Um zu testen, ob dieses installiert ist, kann man dieser Anleitung folgen. [...]]]></description>
			<content:encoded><![CDATA[<p>Um Unittests und ggf. weitere Checks direkt aus der IDE zur Ausführung zu bringen, bietet es sich an, diese Funktionalität in die jeweilige Entwicklungsumgebung einzubetten.</p>
<h4>Meine Systemvoraussetzungen:</h4>
<ul>
<li>MacOSX 10.6.4</li>
<li>PDT 1.2</li>
<li>XAMPP für Mac OSX</li>
</ul>
<p>Um <a href="http://www.phpunit.de/">PHPUnit</a> zu installieren,<span id="more-446"></span> wird das <a href="http://pear.php.net/">PEAR</a>-Framework vorausgesetzt. Um zu testen, ob dieses installiert ist, kann man <a href="http://pear.php.net/manual/en/installation.checking.php">dieser Anleitung</a> folgen. Wer, wie ich Xampp unter Mac OSX einsetzt, findet die pear-Binary normalerweise unter:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">/Applications/xampp/xamppfiles/bin</div></div>
<p>.</p>
<p>Um nun PHPUnit zu installieren, geben wir folgende Befehle ein:</p>
<pre class="c">
cd /Applications/xampp/xamppfiles/bin
sudo ./pear channel-discover pear.phpunit.de
sudo ./pear channel-discover pear.symfony-project.com
sudo ./pear install phpunit/PHPUnit
</pre>
<p>Nun sollte PHPUnit installiert sein, was wir mit folgender Anweisung testen können:</p>
<pre class="c">
cd /Applications/xampp/xamppfiles/bin
sudo ./phpunit --version
</pre>
<p>Um nun PHPUnit in PDT zu integrieren, installieren wir uns das Eclipse-Plugin <a href="http://www.phpsrc.org/projects/pti">&#8220;PHP Tool Integration (PTI)&#8221; von PHPsrc</a>.<br />
Zur <a href="http://www.phpsrc.org/projects/pti/wiki/Installation">Installation des Plugins</a>:</p>
<ol>
<li>PDT > Help > Install New Software &#8230;</li>
<li>Add > http://www.phpsrc.org/eclipse/pti/</li>
<li>Dann bei den gewünschten Paketen einen Haken rein und ab dafür.</li>
</ol>
<p>Die letzte Hürde, die wir zu nehmen haben, ist nach dem Neustart von PDT die Konfiguration vom PTI-Plugin.<br />
Hierzu gehen wir wie folgt vor:</p>
<ol>
<li>Eclipse > Einstellungen > PHP > PHP Executables > Add&#8230;
<ul>
<li>Name: PHP</li>
<li>Executable Path: /Applications/xampp/xamppfiles/bin/php</li>
<li>PHP ini file (optional): /Applications/XAMPP/xamppfiles/etc/php.ini</li>
<li>SAPI Type: CLI</li>
<li>PHP Debugger: XDebug</li>
</ul>
</li>
<li>Eclipse > Einstellungen > PHP Tools > PHPUnit > PHP Executables > &#8220;PHP&#8221;</li>
</ol>
<p>Fertig!</p>
<p>Nun stehen einem die Funktionen des PTI-Plugins zur Verfügung, womit sich der Entwicklungsprozess von PHP-Anwendungen noch effektiver gestalten lässt.<br />
Wer zum Beispiel einen Continous Integration Server, wie PHPUnderControl einsetzt, kann mit diesem Plugin, die auf dem CI-Server ausgeführten Tests &#038; Checks (PHPUnit, <a href="http://pear.php.net/package/PHP_CodeSniffer/">PHP_CodeSniffer</a>, <a href="http://github.com/sebastianbergmann/phpcpd">PHPcpd</a>, <a href="http://pdepend.org">PHP Depend</a>) schon einmal lokal prüfen, um die Anzahl der fehlgeschlagenen Builds möglichst gering zu halten.<br />
Verantwortliche Codezeilen für fehlgeschlagene Tests &#038; Checks werden direkt im Code hervorgehoben. </p>
]]></content:encoded>
			<wfw:commentRss>http://christian-renner.eu/development/phpunit-in-pdt-integrieren-unter-macosx-10-6/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Exception im EDT unter Substance 5.x</title>
		<link>http://christian-renner.eu/development/exception-im-edt-unter-substance-5x/</link>
		<comments>http://christian-renner.eu/development/exception-im-edt-unter-substance-5x/#comments</comments>
		<pubDate>Mon, 04 May 2009 16:05:45 +0000</pubDate>
		<dc:creator>Renner</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Java]]></category>
		<category><![CDATA[Programming]]></category>

		<guid isPermaLink="false">http://blog.christian-renner.eu/?p=433</guid>
		<description><![CDATA[Folgende Exception war das Resultat, als ich jüngst in meinem Java-Projekt das veraltete JAR-File des Substance Look &#038; Feels der Version 4.3 mit der aktuellen Version 5.1 überschrieben habe: org.jvnet.substance.api.UiThreadingViolationException: Component creation must be done on Event Dispatch Thread Zugegeben: Es war schon etwas waghalsig zu glauben, dass dies auch einfach so mal gehen kann. [...]]]></description>
			<content:encoded><![CDATA[<p>Folgende Exception war das Resultat, als ich jüngst in meinem Java-Projekt das veraltete JAR-File des Substance Look &#038; Feels der Version 4.3 mit der aktuellen Version 5.1 überschrieben habe:</p>
<pre class="java">
org.jvnet.substance.api.UiThreadingViolationException: Component creation must be done on Event Dispatch Thread
</pre>
<p>Zugegeben: Es war schon etwas waghalsig zu glauben, dass dies auch einfach so mal gehen kann. Aber Hallo? Man darf ja wohl noch träumen.</p>
<p>Die Lösung auf das Problem findet man in folgendem Beitrag und ist gleichermaßen simpel und erschreckend: <a href="http://tuto.dashcircle.com/index.php/component/content/article/1-java2d-java-swing/9-substance-50-and-event-dispatch-thread?tmpl=component&#038;print=1&#038;page=">Substance 5.0 and Event Dispatch Thread</a>.  </p>
<p>Die Quintessenz ist folgende:<span id="more-433"></span> In meiner konkreten Anwendung ist die Initialisierung der GUI in der start-Methode eines Singleton-Application-Objektes eingepackt. Im Konstruktor findet die Einbindung des Substance-Look-and-Feels statt. Im Prinzip also beinahe dieselben Voraussetzungen, wie im oben verlinkten Beispiel des französischen Kollegen. Um die Exception zu vermeiden, muss der Aufruf des GUI-Konstruktors &#8211; wie übrigens auch in jedem <a href="http://java.sun.com/docs/books/tutorial/uiswing/examples/start/HelloWorldSwingProject/src/start//HelloWorldSwing.java">Swing-Tutorial</a> der Welt beschrieben &#8211; in einer Instanz eines neuen Event Dispatch Threads erfolgen.</p>
<p>Und so sieht das dann aus:</p>
<pre class="java">
public static void main(String[] args) {
    java.awt.EventQueue.invokeLater(new Runnable() {
	public void run() {
	    Application application = Application.getInstance();
            application.start();
	}
    });
}
</pre>
<p>Die Klasse</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Application.java</div></div>
<p>sieht in gekürzter Version dann, wie folgt aus:</p>
<pre class="java">
// implementiert das Singleton-Pattern
public class Application {
    // Die einzige Instanz der Klasse Application
    private static Application application = null;

    private Application() {
        JFrame.setDefaultLookAndFeelDecorated(true);
        try {
            UIManager.setLookAndFeel(new SubstanceBusinessBlackSteelLookAndFeel());
        } catch (UnsupportedLookAndFeelException e) {
            System.err.println(e.toString());
        }
    }

    public void start() {
        // Die Klasse UserInterface erbt von JFrame und erzeugt die GUI
        this.ui = new UserInterface();
    }

    public static synchronized Application getInstance() {
        if(this.application == null) {
            this.application = new Application();
        }
        return this.application;
    }
}
</pre>
<p>Fazit: Wer auf dieses Problem stößt (so wie auch der, der es beschreibt) hat wohl die erste Stunde der Swing-Lektionen übersprungen. Der Fehler resultiert einzig und allein aus persönlicher Schlamperei und Faulheit. Was man nun &#8211; mal wieder &#8211; daraus lernt? RTFM <img src='http://christian-renner.eu/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://christian-renner.eu/development/exception-im-edt-unter-substance-5x/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Xampp 1.7.0 und PDO-Extension vertragen sich nicht</title>
		<link>http://christian-renner.eu/development/xampp-170-und-pdo-extension-vertragen-sich-nicht/</link>
		<comments>http://christian-renner.eu/development/xampp-170-und-pdo-extension-vertragen-sich-nicht/#comments</comments>
		<pubDate>Thu, 09 Apr 2009 12:19:15 +0000</pubDate>
		<dc:creator>Renner</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Xampp]]></category>

		<guid isPermaLink="false">http://blog.christian-renner.eu/?p=408</guid>
		<description><![CDATA[Nachdem ich auf die aktuelle Xampp-Version 1.7.0 umgestiegen bin, terminierten einige meiner Web-Anwendungen, die ich in meiner Testumgebung laufen habe mit einer Fehlermeldung des Apache-HTTP-Servers bezüglich folgendem Moduls: AppName: apache.exe AppVer: 2.2.11.0 ModName: php_pdo_mysql.dll Kurzes Googeln brachte die Lösung, dass sich die aktuelle Windows-Version des Xampp-Projektes nicht mit der Nutzung der PDO-Erweiterung verträgt. Eine Problemlösung [...]]]></description>
			<content:encoded><![CDATA[<p>Nachdem ich auf die aktuelle Xampp-Version 1.7.0 umgestiegen bin, terminierten einige meiner Web-Anwendungen, die ich in meiner Testumgebung laufen habe mit einer Fehlermeldung des Apache-HTTP-Servers bezüglich folgendem Moduls:</p>
<pre class="c">AppName: apache.exe  AppVer: 2.2.11.0  ModName: php_pdo_mysql.dll</pre>
<p>Kurzes Googeln brachte die Lösung, dass sich die aktuelle Windows-Version des Xampp-Projektes nicht mit der Nutzung der <a href="http://de.php.net/pdo">PDO-Erweiterung</a> verträgt. Eine Problemlösung (zumindest für Windows XP, SP3) findet sich in folgendem Forenbeitrag: </p>
<p><a href="http://www.apachefriends.org/f/viewtopic.php?f=4&#038;t=32587">Xampp 1.7: Probelem mit PDO MySQL</a> auf appachefriends.org</p>
<blockquote><p>Ersetzen der libmysql.dll in den folgenden Verzeichnissen:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">\xampp\apache\bin</div></div>
<p>und</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">\xampp\php</div></div>
<p>Downloaden kann man diese Bibliothek mit einem aktuellen PHP-Paket:<br />
<a href="http://windows.php.net/downloads/snaps/php-5.2-win32-VC6-x86-latest.zip">http://windows.php.net/downloads/snaps/php-5.2-win32-VC6-x86-latest.zip</a></p></blockquote>
<p>Bei mir hat es wunderbar funktioniert. Probleme kann es in Folge dessen jedoch bei anderen Datenbankadaptern geben (mysqli).</p>
<p>UPDATE: Ein Upgrade des Xampp auf Version 1.7.1 behebt die Problematik.</p>
]]></content:encoded>
			<wfw:commentRss>http://christian-renner.eu/development/xampp-170-und-pdo-extension-vertragen-sich-nicht/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Kuckst du!</title>
		<link>http://christian-renner.eu/development/kuckst-du/</link>
		<comments>http://christian-renner.eu/development/kuckst-du/#comments</comments>
		<pubDate>Mon, 09 Mar 2009 15:39:37 +0000</pubDate>
		<dc:creator>Renner</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[AJAX]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[Hello World]]></category>
		<category><![CDATA[JS]]></category>
		<category><![CDATA[Qooxdoo]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Webdesign]]></category>

		<guid isPermaLink="false">http://blog.christian-renner.eu/?p=385</guid>
		<description><![CDATA[Auf der Suche nach einer freien Alternative zur sehr schicken &#8220;Ext JS&#8221;-Bibliothek für das Erstellen von JavaScript-basierenden RIA&#8217;s bin ich auf das AJAX-Framework qooxdoo (gesprochen: [’ku:ksdu:]) gestoßen. Aktuell liegt es in der Version 0.8.1 vor und wird von der &#8220;1&#038;1 Internet AG&#8221; unter der LGPL entwickelt. Neben der Erstellung von desktop-ähnlichen GUI&#8217;s bietet es ein [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://qooxdoo.org"><img src="http://blog.christian-renner.eu/wp-content/uploads/2009/03/logo_qooxdoo-150x150.jpg" alt="qooxdoo.org" title="qooxdoo.org" width="150" height="150" class="alignright size-thumbnail wp-image-392" /></a><br />
Auf der Suche nach einer freien Alternative zur sehr schicken <a href="http://extjs.com/" target="_blank">&#8220;Ext JS&#8221;-Bibliothek</a> für das Erstellen von JavaScript-basierenden RIA&#8217;s bin ich auf das AJAX-Framework <a href="http://qooxdoo.org" target="_blank">qooxdoo</a> (gesprochen: [’ku:ksdu:]) gestoßen. Aktuell liegt es in der Version 0.8.1 vor und wird von der &#8220;1&#038;1 Internet AG&#8221; unter der <a href="http://creativecommons.org/licenses/LGPL/2.1/">LGPL</a> entwickelt.</p>
<p>Neben der Erstellung von desktop-ähnlichen GUI&#8217;s bietet es ein mächtiges SDK, das dem Entwickler das automatisierte Komprimieren des Quellcodes, Unit-Testing, sowie Erstellen einer API ermöglicht. Ein Überblick über die verschiedenen GUI-Komponenten bietet die Live-Demo: <a href="http://demo.qooxdoo.org/current/demobrowser/" target="_blank">Demo-Browser</a>. </p>
<p>Im Folgenden möchte ich gerne einen kurzen Einstieg in das Framework schildern.<br />
<span id="more-385"></span><br />
Für ein ausführliches Tutorial ist momentan leider keine Zeit. Eventuell wird eines folgen, wenn das Projekt in der endgültigen Version 1 verfügbar ist. Etwas ausführlichere Tutorials gibt es sowohl <a href="http://www.muhuk.com/2008/10/getting-a-little-further-than-hello-world-with-qooxdoo/">englisch-</a> als auch <a href="http://www.lieblingsagentur.tv/blog/2007/09/08/qooxdoo-die-fortsetzung/">deutschsprachig</a>.</p>
<h3>Installation der SDK</h3>
<p>Im Vergleich zu anderen AJAX-Frameworks, wie Prototype und JQuery verfolgt es einen für mich neuen Ansatz in der Entwicklung einer Weboberfläche mit JavaScript. Bisher war ich es gewohnt ein, zwei JS-Dateien im Header des XHTML-Dokumentes einzubinden, um direkt im Anschluss in der gewohnten Entwicklungsumgebung meine Skripte zu erstellen.<br />
Das Arbeiten mit Qooxdoo sieht standardmäßig einen Entwicklungsprozess mit dem mitgelieferten, in Phyton geschriebenen, SDK vor. Hierfür muss zunächst Phyton installiert werden, was unter Windows relativ einfach mit <a href="http://www.activestate.com/Products/activepython/index.mhtml" target="_blank">ActivePhyton</a> zu realisieren ist.<br />
Für andere Plattformen sind weitere Empfehlungen auf der <a href="http://qooxdoo.org/documentation/0.8/requirements#tools" target="_blank">Herstellerseite</a> zu finden. Dort findet man auch die <a href="http://qooxdoo.org/download">aktuelle Version</a> des Frameworks. Hat man sich die aktuelle SDK heruntergeladen, wird diese entpackt (c:\qooxdoo). </p>
<h3>Hallo Welt!</h3>
<p>Um ein neues Projekt mit der Bezeichnung &#8220;helloworld&#8221; (Achtung: Ein Bindestrich im Projektnamen erzeugt einen Fehler zur Laufzeit!) aufzusetzen, öffnen wir die Konsole und geben folgenden Aufruf ein:</p>
<pre class="c">
C:\qooxdoo\tool\bin\create-application.py --name=helloworld --out=C:\xampp\htdocs\
</pre>
<p>Dadurch wird durch das SDK ein Projektverzeichnis mit dem Namen &#8220;helloworld&#8221; im htdocs-Verzeichnis meiner Xampp-Installation erstellt. Das mache ich, da ich die später noch zu erzeugende API über meinen lokalen Webserver verfügbar haben möchte. </p>
<p>Durch das SDK werden in dem Verzeichnis für das Projekt relevante Konfigurationsdateien, sowie eine kleine Hello-World-Anwendung generiert.<br />
Diese beinhaltet einen Button, der durch Drücken ein</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">alert(&quot;Hello World!&quot;);</div></div>
<p>auslöst. Der zugehörige Code befindet sich im Verzeichnis</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">C:\xampp\htdocs\helloWorld\source\class\helloworld\Application.js</div></div>
<p>. </p>
<p>Das obligatorische Hello-World wird also von den Entwicklern bereits mitgeliefert. Um nun trotzdem das Gefühl zu bekommen, etwas geschafft zu haben, werden wir den Button mit einem Tooltip versehen. Hierzu erweitern wir die bereits bestehende &#8220;Application.js&#8221; um folgende Codezeilen:</p>
<pre class="js">
var tooltip = new qx.ui.tooltip.ToolTip("Tipp: Durch Drücken des Buttons wird ihnen die"
                                                   +" Hello-World-Ausgabe angezeigt!");
tooltip.setShowTimeout(50);
button1.setToolTip(tooltip);
</pre>
<p>Das Testen der Anwendung erfordert ein vorheriges Kompilieren der Anwendung. Um die Anwendung zu übersetzen wird folgender Aufruf in die Konsole eingegeben:</p>
<pre class="c">
cd xampp\htdocs\helloworld
generate.py source
</pre>
<p>Die Anwendung lässt sich dann im Browser mittels der URL</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">http://localhost/helloworld/source/</div></div>
<p>testen. </p>
<h3>Deployment und Dokumentation</h3>
<p>Um die Anwendung zu auszuliefern, bietet es sich an den Sourcecode vorher zu bauen. Dazu werden die benötigten Dependencies in eine Datei gepackt und komprimiert. Der Aufruf lautet, wie folgt:</p>
<pre class="c">
generate.py build
</pre>
<p>Alle benötigten Dateien befinden sich anschließend im Verzeichnis</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">C:\xampp\htdocs\helloworld\build</div></div>
<p>und können nun auf den Webserver kopiert werden.</p>
<p>Die projektspezifische API wird durch folgenden Aufruf erzeugt:</p>
<pre class="c">
generate.py api
</pre>
<p>Die API ist dann anschließend über folgende URL verfügbar:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">http://localhost/helloworld/api</div></div>
<p>. </p>
<h3>Fazit</h3>
<p>Ziel des Frameworks ist die Unterstützung von RIA&#8217;s mittels JavaScript ohne tiefgehende Kenntnisse von HTML, CSS und des DOMs. Ob das bis ins Detail tatsächlich der Realität entspricht, kann ich zum jetzigen Zeitpunkt noch nicht sagen. Was ich sagen kann ist:</p>
<p>Das Framework bzw. das SDK ist nach einer kurzen Einarbeitungszeit leicht zu handhaben und sehr gut dokumentiert. Des Weiteren lassen sich sehr schöne GUI&#8217;s entwickeln mit einer Methodik, die stark an die Java-Welt (Swing, SWT) angelehnt ist. Auch die Aufrufe innerhalb des SDK &#8216;s erinnern an Java-Tools (Ant, Maven).<br />
Die integrierte Möglichkeit zur Durchführung von Unit-Tests erlaubt das Skalieren eines JS-Projektes und somit die Entwicklung von &#8220;echten&#8221; RIA&#8217;s. Das Generieren einer API rundet die ganze Sache ab. </p>
<p>Des Weiteren lässt sich durch den RIA-Ansatz ein sehr schönes MVC umsetzen. Das heißt, dass der Gedanke an eine Kombination eines MVC-Server-Frameworks, wie zum Beispiel dem Zend Framework, und dem hier vorliegenden in meinen Augen durchaus lohnenswert ist. Für mein nächstes Projekt wird dieses Gedankenspiel in jedem Fall eine Rolle spielen. Genaueres werde ich berichten, wenn es so weit ist <img src='http://christian-renner.eu/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<p>Live-Link zum Beispiel: <a href="http://projects.christian-renner.eu/qooxdoo/helloworld/" target="_blank">Hallo Welt!</a><br />
Sourcen: <a href="http://projects.christian-renner.eu/qooxdoo/helloworld/qooxdoo_helloworld_source.zip" target="_blank">qooxdoo_helloworld_source.zip</a></p>
]]></content:encoded>
			<wfw:commentRss>http://christian-renner.eu/development/kuckst-du/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Festivalsaison 2009 &amp; das Wunschkonzert</title>
		<link>http://christian-renner.eu/interests/music/festivalsaison-2009-das-wunschkonzert/</link>
		<comments>http://christian-renner.eu/interests/music/festivalsaison-2009-das-wunschkonzert/#comments</comments>
		<pubDate>Fri, 06 Feb 2009 12:02:03 +0000</pubDate>
		<dc:creator>Renner</dc:creator>
				<category><![CDATA[Music]]></category>
		<category><![CDATA[Festivals]]></category>
		<category><![CDATA[Konzerte]]></category>

		<guid isPermaLink="false">http://blog.christian-renner.eu/?p=350</guid>
		<description><![CDATA[Da Ryan Air alle unsere Urlaubsplanungen zerstört hat, indem sie uns sowohl die Flüge für die Kanaren als auch die für Irland gecancelt haben, muss in jedem Fall ein Festival her. Zu allem Unglück fällt &#8211; wie ihr ja alle wisst &#8211; dieses Jahr die Loveparade aus, also muss ich mich schleunigst nach einer Alternative [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.christian-renner.eu/?attachment_id=364" rel="attachment wp-att-364"><img src="http://blog.christian-renner.eu/wp-content/uploads/2009/02/dsc00528-150x150.jpg" alt="Camping lá Merde (RiP 2007)" title="Camping lá Merde (RiP 2007)" width="150" height="150" class="alignright size-thumbnail wp-image-364" /></a><br />
Da Ryan Air alle unsere Urlaubsplanungen zerstört hat, indem sie uns sowohl die Flüge für die Kanaren als auch die für Irland gecancelt haben, muss in jedem Fall ein Festival her.<br />
Zu allem Unglück fällt &#8211; wie ihr ja alle wisst &#8211; dieses Jahr <a href="http://www.drmotte.de/wordpress/2009/01/16/loveparade-2009-abgesagt/">die Loveparade aus</a>, also muss ich mich schleunigst nach einer Alternative umsehen <img src='http://christian-renner.eu/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
Da die Entscheidung schwer fällt hier mein momentanes Brainstorming:<br />
<span id="more-350"></span></p>
<h3>Rock im Park / Rock am Ring</h3>
<p>Ort: <a href="http://maps.google.de/maps?f=q&#038;source=s_q&#038;hl=de&#038;geocode=&#038;q=n%C3%BCrnberg+dutzendteich&#038;sll=49.425602,11.128206&#038;sspn=0.018898,0.05579&#038;gl=de&#038;ie=UTF8&#038;ll=49.417842,11.120396&#038;spn=0.037801,0.11158&#038;t=h&#038;z=14">Nürnberg</a> / <a href="http://maps.google.de/maps?f=q&#038;source=s_q&#038;hl=de&#038;q=N%C3%BCrburgring,+Rheinland-Pfalz&#038;sll=47.54803,19.063425&#038;sspn=0.039221,0.11158&#038;ie=UTF8&#038;cd=1&#038;geocode=FT04AAMdNU9qAA&#038;split=0&#038;t=h&#038;z=13&#038;iwloc=addr">Nürburgring</a><br />
Datum: 5. bis 7. Juni<br />
Preis: 135 € inkl. Parken und Campen (bis 15.03.)</p>
<p>Billy Talent · Bloc Party · Bring Me The Horizon · Dragonforce · Dredg · Enter Shikari · Flogging Molly · Gallows · Jan Delay &#038; Disko No. 1 · Juliette Lewis · Kettcar · Kilians · Killswitch  Engage · Korn · Limp Bizkit · Mando Diao · Marilyn Manson · Middle Class Rut · Peter, Björn &#038; John · Peter Fox · Placebo · Polarkreis 18 · Scouting For Girls · Selig · The Gaslight Anthem · Slipknot · The Killers · The Kooks · The Prodigy · The Script · The Subways · Tomte · Trivium · Volbeat</p>
<h3>Hurricane / Southside</h3>
<p>Ort: <a href="http://maps.google.de/maps?f=q&#038;source=s_q&#038;hl=de&#038;ie=UTF8&#038;cd=1&#038;geocode=FSVKKwMdrrGQAA&#038;split=0&#038;t=h&#038;layer=x&#038;g=Schee%C3%9Fel,+Rotenburg+(W%C3%BCmme),+Niedersachsen&#038;ll=53.159844,9.546604&#038;spn=0.069681,0.22316&#038;z=13">Scheeßel</a> / <a href="http://maps.google.de/maps/ms?msa=0&#038;msid=104573032255977244778.00000111effa0a6c213db&#038;gl=de&#038;hl=de&#038;ie=UTF8&#038;ll=47.976593,8.904161&#038;spn=0.01945,0.05579&#038;t=h&#038;z=15">Neuhausen ob Eck</a><br />
Datum: 19. bis 21. Juni<br />
Preis: 115 € inkl. Parken und Campen</p>
<p>Die Ärzte · Ben Harper and Relentless7 · Blood Red Shoes · Clueso · Culcha Candela · Dendemann · Disturbed · Editors · Eskimo Joe · Fettes Brot · Franz Ferdinand · Get Well Soon · Gogol Bordello · Johnossi · Karamelo Santo · Katy Perry · Kings Of Leon · Kraftwerk · Moby · The Gaslight Anthem · The Sounds · The Whip · The Wombats · Tomte</p>
<h3>Roskilde Festival</h3>
<p>Ort: <a href="http://maps.google.de/maps?oe=utf-8&#038;client=firefox-a&#038;ie=UTF8&#038;hl=de&#038;t=h&#038;layer=x&#038;g=roskilde&#038;ll=55.615298,12.098093&#038;spn=0.032816,0.11158&#038;z=14">Roskilde, Dänemark</a><br />
Datum: (28. Juni), 2. Juli bis 5. Juli<br />
Preis: <a href="http://www.fkpscorpio.com/tickets_bestellung.asp?nummer=190023">ab 246 € inkl. Parken und Campen</a></p>
<p>Coldplay · Madness · Slipknot</p>
<h3>Sziget-Festival</h3>
<p>Ort: <a href="http://maps.google.de/maps?f=q&#038;source=s_q&#038;hl=de&#038;geocode=&#038;q=%C3%93budai+sziget&#038;sll=51.151786,10.415039&#038;sspn=18.698556,57.128906&#038;ie=UTF8&#038;ll=47.54803,19.063425&#038;spn=0.039221,0.11158&#038;t=h&#038;z=14">Donauinsel &#8220;Óbudai Sziget&#8221; in Budapest, Ungarn</a><br />
Datum: 12. bis 17. August<br />
Preis: 150 € inkl. Parken und Campen</p>
<p>Line-Up noch nicht bekanntgegeben. Momentan läuft noch die <a href="http://www.sziget.hu/festival_german/news/124523.html">Wunschmaschine</a>, bei der man sich 10 Bands für das diesjährige Festival wünschen darf. Fast so schön wie Weihnachten. Wenn meine Wahl angenommen wird wäre das Line-Up also folgendes:</p>
<p>AC/DC · Billy Talent · Franz Ferdinand · Gogol Bordello · Kaiser Chiefs · Mando Diao · Mattafix · Perkalaba · Red Hot Chilli Peppers · The Hives<br />
(ja gut etwas übertrieben, aber wir sind hier ja bei <a href="http://de.wikipedia.org/wiki/W%C3%BCnsch_Dir_was">Wünsch-Dir-Was</a>)</p>
<p>Line-Up der letzten Jahre: <a href="http://www.sziget.hu/fesztival/sajto/fellepok2008/">2008</a> <a href="http://www.sziget.hu/fesztival/sajto/sajtofotok2007/koncertek">2007</a></p>
<h3>FM4 FREQUENCY Festival</h3>
<p>Ort: <a href="http://maps.google.de/maps?f=q&#038;source=s_q&#038;hl=de&#038;geocode=&#038;q=Salzburgring,+%C3%96sterreich&#038;sll=50.346045,6.967093&#038;sspn=0.074162,0.22316&#038;g=N%C3%BCrburgring,+Rheinland-Pfalz&#038;ie=UTF8&#038;ll=47.820417,13.173337&#038;spn=0.019508,0.05579&#038;t=h&#038;z=15">Salzburgring, Österreich</a><br />
Datum: 20. bis 22. August<br />
Preis: 95 € inkl. Parken &#038; Campen</p>
<p>Auch hier steht noch kein Line-Up fest. Das dürfte sich jedoch in den nächsten Wochen ändern.<br />
Line-Up der letzten Jahre: <a href="http://www.gig-guide.de/festival/36596/fm4frequency">2008</a> <a href="http://www.festivalhopper.de/festival/tickets/fm-4-frequency-festival-2007.php">2007</a></p>
<h3>&#8230; und zum Schluss:</h3>
<p>Ich werde diese Zusammenstellung natürlich ständig aktualisieren, sobald sich etwas neues ergibt. Immer mal wieder reinschauen lohnt sich also <img src='http://christian-renner.eu/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /><br />
Wer Anregungen zu Festivals hat, die musikalisch in meine Ecke passen (siehe Wunsch-Line-Up beim Sziget), darf gerne einen Kommentar dazu hinterlassen.</p>
<p>Alle Angaben ohne Gewähr. Insbesondere Preisangaben können abweichen. Stand: 10.02.2009</p>
]]></content:encoded>
			<wfw:commentRss>http://christian-renner.eu/interests/music/festivalsaison-2009-das-wunschkonzert/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework &#8211; Tutorial 2. Teil &#8211; Von der Anfrage zum Controller</title>
		<link>http://christian-renner.eu/development/zend-framework-tutorial-2-teil-von-der-anfrage-zum-controller/</link>
		<comments>http://christian-renner.eu/development/zend-framework-tutorial-2-teil-von-der-anfrage-zum-controller/#comments</comments>
		<pubDate>Sat, 31 Jan 2009 11:38:28 +0000</pubDate>
		<dc:creator>Renner</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Zend]]></category>

		<guid isPermaLink="false">http://blog.christian-renner.eu/?p=296</guid>
		<description><![CDATA[Der zweite Teil des Tutorials zum professionellen Einsatz des Zend Frameworks baut auf den ersten Teil auf. In diesem wurde dargestellt, wie das Framework installiert wird. Die Funktionstüchtigkeit wurde dann mit einem obligatorischen &#8220;Hello World&#8221; geprüft. Des Weiteren wurde kurz dargestellt, wie Controller definiert werden und wie diese implitizit über die URL aufgerufen werden. Auch [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.christian-renner.eu/development/zend-framework-tutorial-2-teil-von-der-anfrage-zum-controller/attachment/zend_framework_tutorial_teil2/" rel="attachment wp-att-316"><img src="http://blog.christian-renner.eu/wp-content/uploads/2009/01/zend_framework_tutorial_teil2-150x150.jpg" alt="zend_framework_tutorial_teil2" title="zend_framework_tutorial_teil2" width="150" height="150" class="alignright size-thumbnail wp-image-316" /></a><br />
Der zweite Teil des Tutorials zum professionellen Einsatz des Zend Frameworks baut auf den <a href="http://blog.christian-renner.eu/?p=132">ersten Teil</a> auf. In diesem wurde dargestellt, wie das Framework installiert wird. Die Funktionstüchtigkeit wurde dann mit einem obligatorischen &#8220;Hello World&#8221; geprüft. Des Weiteren wurde kurz dargestellt, wie Controller definiert werden und wie diese implitizit über die URL aufgerufen werden. Auch die View-Komponente wurde ansatzweise behandelt und bereits erste, rudimentäre View-Skripte erstellt.</p>
<p>In diesem Teil wollen wir uns anschauen, wie aus einer Anfrage über verschiedene URL&#8217;s bestimmte Controller aufgerufen werden. Daran sind diverse Elemente beteiligt, die wir zum Teil auch schon im ersten Teil des Tutorials benutzt bzw. kennengelernt haben. Auf Grundlagen, wie die Arbeitsweise eines <a href="http://de.selfhtml.org/servercgi/server/index.htm">Webservers</a> (HTTP, mod_rewrite) oder die <a href="http://de.wikipedia.org/wiki/MVC">MVC-Architektur</a> werde ich hier nicht eingehen, da diese Themen an genügend anderen Stellen bereits ausführlichst behandelt werden. Zu den im Folgenden behandelten Komponenten des Zend Frameworks zählen: Front-Controller, Request-Objekt, Router, Dispatcher und der Action-Controller.<br />
<span id="more-296"></span></p>
<h3>Der Front-Controller</h3>
<p>Durch die erstellten Dateien im ersten Teil des Tutorials haben wir den Webserver derart konfiguriert, dass alle Anfragen, die nicht auf statische Dateien verweisen, von der index.php entgegengenommen werden. Dies stellt eine Realisierung des <a href="http://www.martinfowler.com/eaaCatalog/frontController.html">Frontcontroller-Patterns</a> dar, welche im Falle des Zend Frameworks von der Klasse <a href="http://framework.zend.com/manual/de/zend.controller.front.html">Zend_Controller_Front</a> übernommen wird. Des Weiteren gilt zu beachten, dass die Klasse als <a href="http://de.wikipedia.org/wiki/Singleton_(Entwurfsmuster)">Singleton</a> implementiert ist. Das bedeutet, dass es nur eine einzige Instanz dieser Klasse gibt, die über eine statische Methode referenziert werden kann:</p>
<pre class="php">
$frontController = Zend_Controller_Front::getInstance();
</pre>
<p>Danach kann der Front-Controller konfiguriert werden. Dies betrifft zumindest das Setzen eines Pfades zu einem Verzeichnis, das Action-Controller enthält. Da der Front-Controller als Registry eingesetzt wird, kann man zudem bestimmte Objekte und Umgebungsvariablen an diesen übergeben und später wieder abrufen. Wegen seiner Singleton-Eigenschaft sind diese Daten überall in der Anwendung verfügbar.<br />
Folgende, weitere Aufgaben werden vom Front-Controller übernommen:</p>
<ul>
<li>Entgegennehmen der Anfrage</li>
<li>Einbinden von Plugins mit Hilfe eines Plugin-Brokers (ErrorHandler, ViewRenderer)</li>
<li>Weiterleiten des Request-Objekts an einen Router und einen Dispatcher</li>
</ul>
<h3>Das Request-Objekt</h3>
<p>Dieses Objekt der Klasse</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Zend_Controller_Request_Http</div></div>
<p>wird defaultmäßig vom Front-Controller instanziiert und beinhaltet zum einen, wie der Name schon vermuten lässt, die Daten aus dem HTTP-Request (Header-Daten GET/POST-Parameter, Art des Requests, etc.). Des Weiteren enthält das Objekt Informationen, die in der Transformationskette generiert werden, in der es sich befindet:</p>
<ul>
<li>Name des Moduls</li>
<li>Name des Controllers</li>
<li>Name der Action</li>
<li>Weitere Parameter</li>
</ul>
<p>Diese Werte werden nach und nach von den einzelnen &#8220;Beteiligten&#8221; der Transformationskette (Front-Controller, Router, Dispatcher, Action-Controller) gesetzt bzw. abgefragt. Das Request-Objekt kann auch manuell erstellt werden und während des Bootstrappings dem Front-Controller übergeben werden. Dies ist ratsam, wenn man HTTP-Requests im Vorfeld bearbeiten möchte oder andere Protokolle (<a href="http://webfractor.wordpress.com/2008/08/14/using-zend-framework-from-the-command-line/">CLI</a>, <a href="http://devzone.zend.com/article/3779-Create-your-own-widget-with-PHP-GTK">PHP-GTK</a>) einsetzen möchte. In diesen Fällen erweitert man die Basisklasse (Zend_Controller_Request_Abstract) und übergibt ein entsprechendes Objekt an die</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">dispatch()</div></div>
<p>-Methode. In unserem Kontext (Webanwendung) wird dies jedoch nicht benötigt werden.</p>
<h3>Das Routing</h3>
<p>Mit Routing ist das Extrahieren der aufzurufenden Action an einem bestimmten Action-Controller und der Identifizierung weiterer Parameter gemeint. Übernommen wird diese Aufgabe im Default-Fall vom Standardrouter der Klasse</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Zend_Controller_Router_Rewrite</div></div>
<p>. Dieser setzt ein URL-Rewriting voraus und enthält einen Satz von Regeln, die festlegen, wie die gewünschten Informationen aus einer URL extrahiert werden sollen. Beides wurde bereits im vorangehenden Teil des Tutorials beschrieben. Die Standardrouten können natürlich ergänzt werden. Hierzu stehen dem Entwickler vier Klassen von Routen zur Verfügung:</p>
<ul>
<li>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Zend_Controller_Router_Route</div></div>
</li>
<li>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Zend_Controller_Router_Route_Static</div></div>
</li>
<li>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Zend_Controller_Router_Route_Regex</div></div>
</li>
<li>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Zend_Controller_Router_Route_Hostname</div></div>
</li>
</ul>
<p>Die erste Klasse dient dazu das Standardrouting dahingehend zu erweitern, dass für einen bestimmten Wert, welcher den zu benutzenden Controller entsprechen würde, festgelegt wird, dass der zweite angegebene Wert nicht auf die Action des Controllers verweist, sondern als Parameterübergabe aufgefasst wird.<br />
Beispiel: Für die URL</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">http://XSampleBlog/search/auto</div></div>
<p>soll nicht die Action &#8220;autoAction&#8221; im Controller &#8220;searchController&#8221; aufgerufen werden, sondern lediglich nach der Phrase &#8220;auto&#8221; gesucht werden. Hierzu erweitert man den Regelsatz des Routers, um eine entsprechende Route, mittels folgender Anweisung:</p>
<pre class="php">
$newRoute = new Zend_Controller_Router_Route('search/:phrase',
    array('controller' => 'search', 'action' => 'index'));
$router->addRoute('search', $newRoute);
</pre>
<p>Hier wird also durch den Doppelpunkt festgelegt, dass es sich bei dem Wert &#8220;auto&#8221;, um einen Parameter des Typs &#8220;phrase&#8221; handelt und am &#8220;searchController&#8221; die Methode &#8220;indexAction&#8221; aufgerufen werden soll. Der Parameter &#8220;phrase&#8221; wird, wie die anderen Werte (Modul-, Controller- und Actionname) auch, im Request-Objekt gespeichert und ist über dieses dann im Action-Controller verfügbar:</p>
<pre class="php">
// Aufruf im searchController
$request = $this->getRequest();
$phrase = $request->getParam('phrase');
</pre>
<p>Die anderen Router-Klassen werden ähnlich verwendet. Eine ausführliche Darstellung mit Beispielen findet sich im <a href="http://framework.zend.com/manual/de/zend.controller.router.html">Programming-Guide</a> des Herstellers.</p>
<h3>Der Dispatcher</h3>
<p>Der Standard-Dispatcher</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">Zend_Controller_Dispatcher_Standard</div></div>
<p>übernimmt anschließend den Part, die vom Router festgestellten Werte für <a href="http://framework.zend.com/manual/de/zend.controller.modular.html">Modul</a>, Controller und Action aus dem Request-Objekt auszulesen und die entsprechende Methode aufzurufen. Fehlende Werte werden durch defaults aufgefüllt. Diese Default-Werte können mittels entsprechenden Setter-Methoden gesetzt werden. Ansonsten sind die Default-Werte wie folgt gesetzt:</p>
<ul>
<li>&#8216;default&#8217; für Modul</li>
<li>&#8216;index&#8217; für Controller</li>
<li>&#8216;index&#8217; für Action</li>
</ul>
<p>Der Dispatcher sitzt am Ende der Transformationskette des Request-Objekts bevor es an den jeweiligen Action-Controller weitergegeben wird. Mittels der Methode</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">forward()</div></div>
<p>kann diese Transformationskette aus dem Action-Controller heraus erneut angestoßen werden. </p>
<h3>Der Action-Controller</h3>
<p>Die Aufgaben des Action-Controllers sind im Prinzip erst einmal unklar. Es ist allein eine Designfrage, welche Aufgabe man ihm zuspricht. Ich habe erst letztens <a href="http://blog.astrumfutura.com/archives/373-The-M-in-MVC-Why-Models-are-Misunderstood-and-Unappreciated.html">gelesen</a>, dass man ihm eigentlich so wenig wie möglich Logik zuweisen und die Businesslogik in das Modell verlegen soll. Der Vorteil, der bei sogenannten &#8220;Fat Models&#8221; entstehe, liege in der höheren Modularisierungs- und der damit verbundenen Re-Use-Fähigkeit. Die Aufgaben des Controllers liegen dann nur in der Zuteilung der jeweiligen Modelklassen zu einer Anfrage. Für jetzt und hier ist dieses Thema jedoch noch zu früh. Auf sinnvolle Architekturen werde ich in einem späteren Teil des Tutorials noch einmal eingehen. </p>
<p>Im Wesentlichen liegt die Aufgabe des Controllers darin, der View-Komponente zu sagen, was sie darstellen soll. Diese Erkenntnis gewinnt er unmittelbar aus dem Request-Objekt und aus dem was der Entwickler festgelegt hat, was er in entsprechenden Fällen zu tun hat. Entsprechend der Anfrage zieht er also das eine oder andere Model-Objekt aus dem Speicher, modifiziert es gegebenenfalls oder erweitert das Datenmodell anhand der im Request-Objekt übermittelten Daten und übergibt diese Teilmenge dem View-Skript. Das wars. Mehr macht der Controller nicht. Ob man dieses Zusammensuchen und Transformieren von Daten nun in eine eigene Modelklasse auslagert, bleibt dann denke ich jedem selbst überlassen.</p>
<p>So das war es für dieses Mal. Ich hoffe euch hat das eher etwas theoretische Tutorial einen Einblick verschaffen können, welche Aufgaben die einzelnen Komponenten des Zend Frameworks übernehmen. Bei Fragen oder Problemen darf natürlich gerne ein Kommentar hinterlassen werden. Der nächste Teil folgt in den nächsten Tagen. Bis dahin wünsche ich allen ein gutes Gelingen.</p>
]]></content:encoded>
			<wfw:commentRss>http://christian-renner.eu/development/zend-framework-tutorial-2-teil-von-der-anfrage-zum-controller/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Cebit 2009 – I’ll be back …</title>
		<link>http://christian-renner.eu/development/cebit-2009-ill-be-back/</link>
		<comments>http://christian-renner.eu/development/cebit-2009-ill-be-back/#comments</comments>
		<pubDate>Mon, 26 Jan 2009 13:41:11 +0000</pubDate>
		<dc:creator>Renner</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Cebit]]></category>
		<category><![CDATA[Green IT]]></category>
		<category><![CDATA[Hannover]]></category>
		<category><![CDATA[ICT]]></category>
		<category><![CDATA[Kalifornien]]></category>
		<category><![CDATA[Webciety]]></category>

		<guid isPermaLink="false">http://blog.christian-renner.eu/?p=265</guid>
		<description><![CDATA[&#8220;Wer die Welt bewegt, bewegt sich hier.&#8221; Gemeint ist das Messegelände im Süden meiner momentanen Lebensabschnittsheimat Hannover. Das diesjährige Motto der weltgrößten ICT-Messe ist großspurig, wie auch schon die Jahre zuvor. Dieses Jahr ist es jedoch berechtigt. Dieses Jahr hat die Cebit einen Partner, wie es man sich für DIE Messe nicht besser träumen kann: [...]]]></description>
			<content:encoded><![CDATA[<p>&#8220;Wer die Welt bewegt, bewegt sich hier.&#8221; Gemeint ist das Messegelände im Süden meiner momentanen Lebensabschnittsheimat Hannover. Das diesjährige Motto der weltgrößten <a href="http://de.wikipedia.org/wiki/Informations-_und_Kommunikationstechnologie">ICT</a>-Messe ist großspurig, <a href="http://www.neijman.de/wo-aus-null-und-eins-millarden-werden/">wie auch schon die Jahre zuvor</a>. Dieses Jahr ist es jedoch berechtigt. Dieses Jahr hat die Cebit einen Partner, wie es man sich für DIE Messe nicht besser träumen kann: Den <a href="http://www.cebit.de/7513?pm=cb09-023-d">Governator</a>.</p>
<p style="padding-left: 30px;"><object width="425" height="344" data="http://www.youtube.com/v/C8I4zFSipKs&amp;hl=de&amp;fs=1" type="application/x-shockwave-flash"><param name="allowFullScreen" value="true" /><param name="allowscriptaccess" value="always" /><param name="src" value="http://www.youtube.com/v/C8I4zFSipKs&amp;hl=de&amp;fs=1" /><param name="allowfullscreen" value="true" /></object></p>
<p>Ob der Terminator höchstpersönlich auf der Cebit erscheinen wird, ist unklar. In einem <a href="http://www.cebit.de/suche/intern/kelly/kelly_on_tour.php?page=tour">Interview</a> sagte er, er würde alles in seiner Macht stehende dafür tun, auf der Messe anwesend zu sein. Aufgrund der kurzen Distanz zum Messegelände und des Besitzes (bisher) einer Freikarte, werde ich in jedem Fall wieder zum ehemaligen Expo-Gelände pilgern und etwas von der großen, weiten IT-Welt in mich aufsaugen. Größter Vorteil dieses Jahr ist, dass ich die Möglichkeit habe auch unter der Woche schon auf die Messe zu gehen. Dadurch kann ich zum einen dem Familien-Beutelratten-Strom ausweichen und zum anderen eine der angekündigten <a href="http://www.cebit.de/cgc_program">Keynotes</a> lauschen. Um Letztere soll es nun auch im Weiteren gehen, auch wenn man über Beutelratten ebenso locker einen ganzen Blogeintrag füllen könnte.<br />
<span id="more-265"></span></p>
<h3>Die Themen der Keynotes</h3>
<p>Während auf der <a href="http://www.cebit.de/56338">letztjährigen</a> Cebit das Buzzword &#8220;Green IT&#8221; in aller Munde umhergeisterte, haben sich die Messeplaner es sich nicht nehmen lassen, das diesjährige Programm an einem weiteren auszurichten: <a href="http://www.cebit.de/webciety_d">Webciety</a>. Eine wunderhübsche Wortschöpfung, wogegen der Rest der Hauptthemen, da bekannt, einem doch eher muffig vorkommen:</p>
<ul>
<li>Webciety</li>
<li>Security</li>
<li>Green IT</li>
<li>eHealth</li>
<li>Mobility</li>
</ul>
<p>Betrachtet man die Topics der Keynotes der &#8220;Global Conferences&#8221; vom 3. bis 6. März genauer, darf man jedoch aufatmen, da bis auf Mobility, die anderen Themen weitgehend ausgeklammert bleiben. Am ersten von vier Tagen dreht es sich um die grundsätzlichen Auswirkungen der ICT auf die globale Gesellschaft. Durch Beiträge von Vertretern der Branchengrößen (Microsoft, SAP, Alcatel-Lucent, Intel) und dem anschließenden Panel werden die Weichen gestellt, um den Rest der Woche die technischen Fortschritte, die nicht nur mittels Keynotes, sondern speziell auch durch die vielen Aussteller und deren Produkte, vermittelt werden, besser aufzunehmen und unter einem sozialen, globalen Gesichtspunkt zu sehen.<br />
Am zweiten Tag der Cebit wird die <a href="http://www.hans-bredow-institut.de/webzweinull/2008/09/04/medienkonvergenz-monitoring-report-2008/">Medienkonvergenz</a> thematisiert. Die Vertreter sind mittels Keynotes T-Mobile, Skype, XING und Acer, sowie im Panel unter anderem <a href="http://de.wikipedia.org/wiki/Helmut_Thoma_(Manager)">Helmut Thoma</a>. Wer den charismatischen Ex-RTL-Chef mag, sollte sich das genau so wenig entgehen lassen, wie die abendlich stattfindende Verleihung des <a href="http://www.convergators.de/">&#8220;Convergators Awards&#8221;</a>, in dessen Rahmen derselbige eine Laudatio halten wird.<br />
Der vorletzte Tag steht ganz im Zeichen der Wirtschaftskraft, die hinter der ICT steht. Während zum einen Blicke auf die Krise geworfen werden sollen, steht auf der anderen Seite die immense Innovationskraft, die auch in Zukunft die Triebfeder für die Wirtschaft sein soll. In diesem Zusammenhang werden die Vertreter großer Wirtschaftsunternehmen, wie Dell, IBM, Porsche und andere, ihre Visionen für die Zukunft zum Besten geben.<br />
Am vierten und letzten Konferenztag wird noch einmal die Rolle des Internets im Zusammenhang mit der Webciety herausgestellt. Vertreter der Global Player des &#8220;Web 2.0&#8243; (Linkedln, Flickr, Yahoo, Amazon, MySpace, Ciao) gehen auf die aktuellen Trends (<a href="http://www.wired.com/techbiz/it/magazine/16-05/mf_amazon">&#8220;Cloud Computing&#8221;</a>, Amazon) und die Zukunft des Webs ein.</p>
<h3>Und sonst?</h3>
<p>Natürlich hat die Cebit neben den offiziellen Konferenzen noch viel mehr zu bieten. Was ich jedoch aus meinen Besuchen auf der Messe bisher gelernt habe, ist sich nicht zu viel vorzunehmen, ansonsten kann einen die Vielfalt an neuen Ideen und Produkten erschlagen. Wer sich für eine der oben genannten Keynotes oder Panels eingetragen hat, kann sich im Zuge dessen auch gleich für eine &#8220;<a href="http://www.cebit.de/cgc_guidedtours">Guided Tour</a>&#8221; anmelden. So verpasst man für das jeweilige Thema garantiert nichts.<br />
Wer den Luxus hat, mehrere Tage auf die Messe gehen zu können, sollte dies ausnutzen. Ansonsten muss man zwangsweise Abstriche machen. Auf jeden Fall zu empfehlen ist Halle 9. Dort befindet sich neben den Ständen der einzelnen Bundesländer auch der Future Parc. Verschiedene Institute präsentieren hier ihre neuesten Forschungsergebnisse. Gerade das Fraunhofer Institut ist in dieser Beziehung meist für eine Überraschung gut. Ansonsten dürfte es dieses Jahr wohl in der Halle 6 zu Gedränge kommen. Neben dem Hauptpavillon Kaliforniens, wo man im Zweifelsfall den Governator antreffen dürfte, sind hier die <a href="http://www.cebit.de/ims_d">Internet &amp; Mobile Solutions</a> zu finden, welche eines der Hauptthemen dieses Jahr darstellen. Was gegen Abend auch immer zu empfehlen ist, sind die <a href="http://www.netzwelt.de/news/70370-cebit-partyspass-bei-freenet.html">Partystände</a>, an denen man den stressigen Messealltag ausklingen lassen kann.</p>
<p>Also denn, vielleicht sieht man sich ja dann im März, wenn es heißt: I&#8217;ll be back &#8230;</p>
]]></content:encoded>
			<wfw:commentRss>http://christian-renner.eu/development/cebit-2009-ill-be-back/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Hosen runter &#8211; Impressumspflicht in Deutschland</title>
		<link>http://christian-renner.eu/interests/web/hosen-runter-impressumspflicht-in-deutschland/</link>
		<comments>http://christian-renner.eu/interests/web/hosen-runter-impressumspflicht-in-deutschland/#comments</comments>
		<pubDate>Wed, 21 Jan 2009 11:24:02 +0000</pubDate>
		<dc:creator>Renner</dc:creator>
				<category><![CDATA[Web]]></category>
		<category><![CDATA[Impressum]]></category>
		<category><![CDATA[Informationspflicht]]></category>
		<category><![CDATA[Medienrecht]]></category>
		<category><![CDATA[TMG]]></category>

		<guid isPermaLink="false">http://blog.christian-renner.eu/?p=258</guid>
		<description><![CDATA[Das fehlende Impressen zu empfindlichen Abmahngebühren gegenüber Verbraucherschutzverbänden oder auch Wettbewerben führen kann, dürfte sich herumgesprochen haben. Wie man sich dagegen schützen kann? Naja, die Antwort liegt auf der Hand: In dem man ein Impressum auf seiner Webpräsenz angibt. Was es dabei zu beachten gilt, wird im folgenden dargestellt. Wer braucht was? Wer ein Impressum [...]]]></description>
			<content:encoded><![CDATA[<p>Das fehlende Impressen zu empfindlichen Abmahngebühren gegenüber Verbraucherschutzverbänden oder auch Wettbewerben führen kann, dürfte sich herumgesprochen haben. Wie man sich dagegen schützen kann? Naja, die Antwort liegt auf der Hand: In dem man ein Impressum auf seiner Webpräsenz angibt. Was es dabei zu beachten gilt, wird im folgenden dargestellt.</p>
<h3>Wer braucht was?</h3>
<p>Wer ein Impressum benötigt ist gesetzlich geregelt. Zum einen geht dies aus dem Telemediengesetz (<a href="http://www.gesetze-im-internet.de/tmg/">TMG</a>) und zum anderen aus dem Rundfunkstaatsvertrag (<a href="http://www.lfk.de/gesetzeundrichtlinien/rundfunkstaatsvertrag/main.html">RStV</a>) hervor. Der §55 RStV unterscheidet zwei Arten von Telemedien. Zum einen besagt er, dass &#8220;Telemedien, die nicht ausschließlich persönlichen oder familiären Zwecken dienen&#8221;, folgende Angaben machen müssen:<br />
<span id="more-258"></span></p>
<ul>
<li>Name und Anschrift des Anbieters</li>
<li>handelt es sich beim Anbieter um eine juristische Person, Name und Anschrift des gesetzlichen Vertreters</li>
<li>handelt es sich um einen journalistisch-redaktionellen Telemediendienst, jeweils den Namen und die Anschrift des für den jeweiligen redaktionellen Bereich Verantwortlichen</li>
</ul>
<p>Neben dem Rundfunkstaatsvertrag regelt das Telemediengesetz die Informationspflicht eines Anbieters. Aus §5 TMG geht hervor, dass Diensteanbieter &#8211; zusätzlich zu oben genannten Informationen &#8211; &#8220;für geschäftsmäßige, in der Regel gegen Entgelt angebotene Telemedien folgende Informationen leicht erkennbar, unmittelbar erreichbar und ständig verfügbar zu halten&#8221; haben:</p>
<ul>
<li>Angaben, die eine schnelle elektronische Kontaktaufnahme und unmittelbare Kommunikation mit ihnen ermöglichen (EMail-Adresse, etc.)</li>
<li>Aufsichtsbehörde bei Diensten die einer Zulassung bedürfen</li>
<li>Registernummern und Bezeichnung der Register in die der Anbieter eingetragen ist (HRB, etc.)</li>
<li>Umsatzsteueridentifikationsnummer (wenn vorhanden)</li>
<li>Zusätzliche Angaben bei bestimmten Berufsgruppen</li>
<li>Angabe, ob sich die Kapitalgesellschaft in Liquidation befindet</li>
</ul>
<h3>Die Two-Step-Regel</h3>
<p>Nach aktueller Rechtssprechung muss ein Impressum mit zwei Links gefunden werden können. Ein Link mit der Bezeichnung &#8220;Kontakt&#8221; hinter dem sich der Link &#8220;Impressum&#8221; verbirgt, wäre demnach noch zu vertreten. Es gibt jedoch auch die andere Seite der Rechtssprechung, wonach ein Link zum Impressum, den man nur durch Scrollen finden kann, unzulässig ist. Möchte man auf Nummer &#8220;Sicher&#8221; gehen, sollte man das Impressum also leicht findbar auf der Startseite integrieren. Üblicherweise wird es auch im Footer der Seite eingebunden, was zwar der Nicht-Scroll-Regel widerspricht, aber da es der Nutzer dort erwartet, trotzdem leicht zu finden ist. Normalerweise spricht ja aber auch nichts dagegen, dass der Nutzer das Impressum schnell findet. Im Gegenteil. Da im Impressum die Kontaktdaten enthalten sind und eine Kontaktaufnahme von Seiten des Nutzers eigentlich immer erwünscht sein sollte.</p>
<h3>Fazit: Mehr ist manchmal weniger</h3>
<p>Was lässt sich nun also abschließend zu sagen? Kommerzielle oder redaktionell arbeitende Dienste benötigen in jedem Fall ein ausführiches Impressum. Private Webseitenbetreiber haben grundsätzlich keine Impressumspflicht. Da das Abwägen, ob man wirklich keine geschäftsmäßigen Informationen bereitstellt nicht unbedingt trivial ist, sollte man darüber nachdenken, in jedem Fall ein Impressum mit Name, Anschrift und Kontaktmöglichkeit anzubieten. Mehr Angaben reduzieren das Risiko einer Abmahnung auf eine Wahrscheinlichkeit von 0%. Mehr ist als manchmal doch weniger <img src='http://christian-renner.eu/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
]]></content:encoded>
			<wfw:commentRss>http://christian-renner.eu/interests/web/hosen-runter-impressumspflicht-in-deutschland/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Zend Framework &#8211; Tutorial 1. Teil &#8211; Hello World</title>
		<link>http://christian-renner.eu/development/zend-framework-tutorial-1-teil-hello-world/</link>
		<comments>http://christian-renner.eu/development/zend-framework-tutorial-1-teil-hello-world/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 14:01:20 +0000</pubDate>
		<dc:creator>Renner</dc:creator>
				<category><![CDATA[Development]]></category>
		<category><![CDATA[Framework]]></category>
		<category><![CDATA[Hello World]]></category>
		<category><![CDATA[MVC]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[PHPUnit]]></category>
		<category><![CDATA[Tutorial]]></category>
		<category><![CDATA[Zend]]></category>

		<guid isPermaLink="false">http://blog.christian-renner.eu/?p=132</guid>
		<description><![CDATA[Leider ist mein Tutorial nach der Einführung von Zend_Application (ab ZF 1.8) nicht mehr auf dem aktuellen Stand. Das Tutorial basiert auf einer veralteten Version (ZF 1.7). Da ich momentan sehr eingespannt bin, habe ich momentan leider auch nicht die Zeit, die entsprechenden Teile zu aktualisieren. Zudem steht auch schon seit einiger Zeit der Release [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://blog.christian-renner.eu/development/zend-framework-tutorial-1-teil-hello-world/attachment/zend_framework_tutorial_teil1/" rel="attachment wp-att-233"><img src="http://blog.christian-renner.eu/wp-content/uploads/2009/01/zend_framework_tutorial_teil1-150x150.jpg" alt="Zend Framework - Tutorial 1. Teil - Hello World" title="Zend Framework - Tutorial 1. Teil - Hello World" width="150" height="150" class="alignright size-thumbnail wp-image-233" /></a><br />
Leider ist mein Tutorial nach der Einführung von Zend_Application (ab ZF 1.8) nicht mehr auf dem aktuellen Stand. Das Tutorial basiert auf einer veralteten Version (ZF 1.7). Da ich momentan sehr eingespannt bin, habe ich momentan leider auch nicht die Zeit, die entsprechenden Teile zu aktualisieren. Zudem steht auch schon seit einiger Zeit der Release des ZF 2.0 im Raum, was bestimmt auch noch einige Veränderungen mit sich bringen wird.</p>
<p>Deswegen hier vorerst einmal Linktipps:</p>
<ul>
<li><a href="http://zfwiki.de/">zfwiki.de</a></li>
<li><a href="http://www.zf-tutorials.de/">Zend Framework Tutorial für Anfänger</a></li>
<li><a href="http://www.zfforum.de/forumdisplay.php?f=8">Einsteigerfragen</a></li>
</ul>
<p>Für ein generelles Verständnis halte ich die beiden Teile dennoch nach wie vor geeignet.</p>
<hr/>
<p>Anlässlich eines Projektes, welches ich mit dem Zend Frameworks umsetzen möchte, dachte ich mir, dass ich gleichzeitig meine Ergebnisse im Rahmen eines Tutorials festhalte, da deutsche Tutorials zu diesem Thema rar sind oder zumindest <a href="http://www.ralfeggert.de/zend-framework-tutorial/">ab einem bestimmten Punkt nicht mehr weiter geführt</a> wurden. Dementsprechend klopfe ich mal auf Holz, dass ich das Ding hier durchziehe <img src='http://christian-renner.eu/wp-includes/images/smilies/icon_wink.gif' alt=';)' class='wp-smiley' /> </p>
<h3>Version und Voraussetzungen</h3>
<p>Zum jetzigen Zeitpunkt (Jan &#8217;09) hat das Framework die Version 1.7.2. Zusätzlich zu den <a href="http://framework.zend.com/manual/de/requirements.html">Systemvoraussetzungen</a>, sollte auch jeder prüfen, ob der Einsatz eines Frameworks für das jeweilige Projekt gerechtfertigt ist, was folgender Abschnitt versucht herauszustellen.</p>
<h3>Wozu ein Framework und warum Zend?</h3>
<p>Zunächst möchte ich die Eigenschaften und Vorteile des Frameworks herausgreifen. Mit Hilfe derer sollte jeder noch einmal genau überlegen, ob er der Komplexität des Frameworks gewachsen ist und die daraus entstehenden Vorteile überhaupt benötigt oder nicht. Diejenigen, die sich dessen sicher sind, können diesen Abschnitt getrost überspringen und direkt mit dem Abschnitt &#8220;Download &amp; Installation&#8221; beginnen. Blutige Anfänger, die bisher noch nie etwas mit PHP oder anderen serverseitigen Skriptsprachen zu tun hatten, sollten sich zunächst durch eines der zahlreich existierenden PHP-Anfänger-Tutorials durcharbeiten. Das wohl bekannteste &#8211; mit dem auch meine Wenigkeit vor einigen Jahren begonnen hat &#8211; ist wohl das <a href="http://tut.php-quake.net/de/index.html">PHP-Tutorial von Quakenet</a>.</p>
<p>Aber nun zu den Vorteilen und Stärken des Zend Frameworks.<br />
<span id="more-132"></span><br />
Die Stärken des Frameworks liegen grob gesagt in zwei Bereichen. Zum einen erweitert es, wie die meisten Frameworks, die PHP-Standardbibliothek um einen nicht unerheblichen Teil an zusätzlichen Klassen (Caching, Datenbank, Userverwaltung, &#8230;) und APIs zu anderen Diensteanbietern (Google, Youtube, &#8230;). Auf der anderen Seite bietet es die Möglichkeit mit relativ geringem Aufwand seine Projekte in einer sauberen Architektur (<a href="http://de.wikipedia.org/wiki/Model_View_Controller">MVC</a>, <a href="http://de.wikipedia.org/wiki/Web_Service">Webservices</a>) umzusetzen. Letzteres benötigt eine gewisse Einarbeitungszeit in die Systematik, wie das Framework MVC umsetzt. Dies kann auf den ersten Blick mühsam erscheinen, lohnt sich aber, da durch die Architektur automatisch eine Trennung der drei Einheiten Datenmodell, Programmlogik und Präsentation erfolgt. Daraus resultiert, vor allem in großen Projekten mit mehreren Entwicklern und Spezialisten (Datenbankprogrammierer, Webdesigner, &#8230;), durch die solide Schnittstellendefinition, eine höhere Stabilität bei Änderungen während der Entwicklungsphase und eine höhere Wartungsfreundlichkeit nach der Auslieferung. Alles in allem wird dadurch die Fehleranfälligkeit reduziert. Durch eine integrierte Testumgebung (<a href="http://framework.zend.com/manual/en/zend.test.html">Zend_Test</a>) lassen sich zudem sehr schnell Unit-Tests erstellen, wodurch sich das Risiko der Fehlerproduktion beim Refactoring oder bei der Umsetzung von Änderungsanforderung während der Entwicklungsphase reduzieren (<a href="http://www.artima.com/weblogs/viewpost.jsp?thread=210575">C.R.A.P. Index</a>) lässt. Wer sich mehr mit dem Thema &#8220;Qualitätssicherung in PHP-Projekten&#8221; befassen möchte, empfehle ich den Blog von <a href="http://sebastian-bergmann.de/">Sebastian Bergmann</a> (PHPUnit, ezComponents). Für Einsteiger ist eventuell <a href="http://sebastian-bergmann.de/archives/714-Qualitaetssicherung-in-PHP-Projekten.html">diese</a> Präsentation hiilfreich.</p>
<p>Ein weiterer Vorteil des Zend Frameworks ist die sehr gute <a href="http://framework.zend.com/manual/de/">Dokumentation</a>. Außerdem erfreut es sich &#8211; Open Source sei Dank &#8211; einer recht großen und aktiven <a href="http://framework.zend.com/wiki/display/ZFDEV/Home">Community</a>, innerhalb welcher sich auch ein <a href="http://www.zfforum.de/index.php">deutschsprachiges Forum</a> etabliert hat.</p>
<p>So viele Möglichkeiten das Framework auch bietet, für die meisten kleinen Projekte, innerhalb derer weder eine Datenbank noch eine Userverwaltung benötigt wird, bringt es einen unvertretbaren Overhead an Speicherplatz und Einrichtungs- bzw. vor allem auch Einarbeitungszeit mit sich. Sobald man sich aber dafür entscheidet ein etwas größeres Projekt umzusetzen, welches eine klar strukturierte Architektur haben oder mittels kleinen Widgets verschiedene Webservices nutzen soll, ohne dass man dabei auf fertige Produkte oder Teilprodukte zurückgreifen will, ist das Zend Framework eine mehr als in Erwägung zu ziehende Alternative.<br />
Eventuell lohnt sich aber auch ein Blick auf Konkurrenzprodukte, wie zum Beispiel <a href="http://cakephp.org/">CakePHP</a> oder <a href="http://www.symfony-project.org/">Symfony</a>.</p>
<p>So nun aber los:</p>
<h3>Download &amp; Installation</h3>
<p>Zunächst beginnen wir mit dem Download der benötigten Komponenten. Um das Framework herunterladen zu können, muss man sich erst einmal registrieren. Je nachdem, wie die spätere Anwendung konzipiert ist, muss man an der Stelle schon die erste Entscheidung treffen, ob man das All-Inclusive-Paket (ca. 25MB, zip) oder die Minimalversion (ca. 4MB, zip) von der <a href="http://framework.zend.com">Herstellerseite</a> herunterladen möchte.<br />
Für Einsteiger und Leute, die später mit dem Dojo Toolkit arbeiten möchten empfehle ich die Vollversion herunterzuladen, da hier das Dojo Toolkit und einige Demos enthalten sind, die man sehr leicht ausprobieren und anschließend anhand des Quelltextes nachvollziehen kann.<br />
Für eine lokale Testumgebung bietet sich eine <a href="http://www.apachefriends.org/de/xampp.html">Xampp-Installation</a> mit einem Editor nach Wahl (z.B. <a href="http://www.aptana.com/studio">Aptana Studio</a> oder als Plugin für Eclipse) an. Da das Framework für die Umsetzung einer MVC-Architektur eingesetzt werden soll, empfiehlt es sich, die auf der Herstellerseite vorgeschlagene Verzeichnisstruktur zu übernehmen.<br />
Diese wird im htdocs-Verzeichnis des Apachen angelegt und sieht dann für ein Beispielprojekt &#8220;XSampleBlog&#8221;, folgendermaßen aus:</p>
<pre>
htdocs/XSampleBlog/
|
|- application/controllers/
|
|- application/views/
|
|- application/views/scripts
|
|- library
|
|- public
</pre>
<p>Nun werden die Klassen des Frameworks, welche sich im library-Verzeichnis der entpackten Dateien (ZendFramework-1.x/library/) befinden, in das library-Verzeichnis unserer soeben erstellten Dateistruktur kopiert. Damit ist die &#8220;Installation&#8221; abgeschlossen.</p>
<h3>Zugriffsschutz und Rewriting mittels htaccess</h3>
<p>Da nur die Dateien, die sich im Verzeichnis &#8220;public&#8221; befinden, öffentlich zugänglich sein sollen, heißt das im Umkehrschluss, dass man die beiden anderen Verzeichnis vor einer Auslieferung durch den Webserver bewahren muss. Da man bei den meisten Webhostern auf die direkte Konfiguration des Webservers keinen Einfluss hat, bleibt nur die Konfiguration mittels htaccess-Dateien. Die beiden Verzeichnisse werden also jeweils mittels einer htaccess-Datei mit folgendem Inhalt bestückt, was eine Auslieferung durch den Webserver verhindert (<a href="http://de.selfhtml.org/servercgi/server/htaccess.htm#ip_bereiche_namen">Vertiefung</a>):</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">deny from all</div></div>
<p>Außerdem muss der Apache so konfiguriert werden, dass die Variable <a href="http://de3.php.net/manual/de/reserved.variables.server.php">$_SERVER['DOCUMENT_ROOT']</a> auf das public-Verzeichnis verweist. In dieses Verzeichnis wird anschließend eine htaccess-Datei mit <a href="http://framework.zend.com/docs/quickstart/create-a-rewrite-rule">Rewrite-Regeln</a> abgelegt. Diese Regeln sorgen dafür, dass für eine gegebene URL, die jeweilige Datei (falls existent) statisch ausgeliefert wird, oder in allen anderen Fällen, die Anfrage dynamisch von der im public-Ordner abgelegten index.php behandelt wird. Die index-Datei entspricht somit einem sogenannten <a href="http://de.wikipedia.org/wiki/Front_Controller">Frontcontroller</a>, welcher alle Anfragen des Nutzers empfängt und an den konkreten Controller übergibt.</p>
<h3>Anlegen der bootstrap- und index-Datei</h3>
<p>Der nächste Schritt ist das Anlegen der bootstrap- und der index-Datei. Die erstere wird von der zweiten eingebunden. Der funktionale Ablauf ist folgender:</p>
<ol>
<li>Setzen von globalen Pfadangaben (APPLICATION_PATH) (index.php)</li>
<li>Aktivieren des <a href="http://framework.zend.com/manual/de/zend.loader.html">Zend_Loader</a> (index.php)</li>
<li>Definition von globalen Konstanten (APPLICATION_PATH, APPLICATION_ENVIRONMENT) (bootstrap.php)</li>
<li>Erzeugen einer Singleton-Instanz des <a href="http://framework.zend.com/manual/de/zend.controller.front.html">Zend_Controller_Front</a> (bootstrap.php)</li>
<li>Registrieren des controller-Verzeichnisses am Frontcontroller (bootstrap.php)</li>
<li>Registrieren des env-Parameters (development, staging, testing, production) am Frontcontroller (bootstrap.php)</li>
<li>Löschen der eben erzeugten Variable $frontcontroller (bootstrap.php)</li>
<li>Dispatchen des Requests am Frontcontroller (index.php)</li>
</ol>
<p>Erläuterungen:<br />
zu 7.: In Schritt 4 wurde die Frontcontroller-Instanz an eine Variable gebunden. Da der Frontcontroller jedoch das Singleton-Pattern implementiert, wird diese Variable nicht mehr benötigt und daher gelöscht.</p>
<p>Die Quellcodes für die beiden Dateien sind auf der <a href="http://framework.zend.com/docs/quickstart/create-a-bootstrap-file">Herstellerseite</a> zu finden. Damit ist die Anwendung vorerst ausreichend konfiguriert, um nun endlich unsere &#8220;Hello World!&#8221;-Ausgabe erzeugen zu können.</p>
<h3>Hello World!</h3>
<p>Unter der Haube wird vom Frontcontroller der Request anhand der übermittelten URL an einen Actioncontroller übergeben. Dies geschieht natürlich nicht willkürlich, sondern folgt folgender Gesetzmäßigkeit. Nehmen wir einmal an, dass die URL &#8220;example.com&#8221; auf unser public-Verzeichnis zeigt. Wird mit der URL kein weiterer Parameter übergeben, wird am Actioncontroller &#8220;IndexController&#8221; die Methode &#8220;indexAction&#8221; aufgerufen. Das selbe Ergebnis würde auch sowohl mit der URL &#8220;example.com/index&#8221; als auch mit der URL &#8220;example.com/index/index&#8221; erreicht. Das Schema ist also:</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">hostname/class/method</div></div>
<p>. Nach diesem Prinzip lassen sich weitere Actioncontroller bzw. deren Methoden aufrufen.<br />
Besteht ein Klassen- bzw. Methodenname aus mehreren Wörtern, wie im Fall von &#8220;HelloWorld&#8221; mit der zugehörigen Methode &#8220;sayHello&#8221;, erfordert dies eine URL mit dem Wert &#8220;example.com/hello-world/say-hello&#8221; oder &#8220;example.com/hello.world/say.hello&#8221;. In diesem Falle wird dann am Actioncontroller mit dem Namen &#8220;HelloWorldController&#8221; die Methode mit dem Namen &#8220;sayHelloAction&#8221; aufruft. In unserem Fall sieht die Klasse &#8220;HelloWorldController&#8221; wie folgt aus:</p>
<pre name="code" class="php">
class HelloWorldController extends Zend_Controller_Action {

    public function indexAction() {
        $this->render('say-hello');
    }

    public function sayHelloAction() {
    }

}
</pre>
<p>Unsere &#8220;Hello World!&#8221;-Klasse hat zwei Methoden. Die Methode &#8220;indexAction&#8221; wird aufgerufen, wenn die URL nur einen Parameter enthält, nämlich den der Klasse. Dieses Prinzip ist analog zu der Eigenschaft des Apache Webservers Requests, die nicht auf eine bestimmte Datei zeigen, auf die index-Datei des jeweiligen Ordners weiterzuleiten. In unserem Fall ruft die Methode &#8220;indexAction&#8221; die <a href="http://framework.zend.com/manual/de/zend.controller.action.html#zend.controller.action.viewintegration.render">render()</a>-Methode auf mit dem Wert &#8220;say-hello&#8221;. Dies hat zur Folge, dass das View Skript mit dem Pfadnamen</p>
<div class="codecolorer-container text default" style="overflow:auto;white-space:nowrap;border:1px solid #9F9F9F;width:435px;"><div class="text codecolorer" style="padding:5px;font:normal 12px/1.4em Monaco, Lucida Console, monospace;white-space:nowrap">application/views/scripts/hello-world/say-hello.phtml</div></div>
<p>gerendert wird. Genau das selbe passiert auch implizit, wenn man diesen Parameter über die URL mitgibt. In dem Fall wird nämlich die zweite Methode unserer Klasse aufgerufen, also &#8220;sayHelloAction&#8221;. Da hier kein expliziter render-Aufruf enthalten ist, wird standardmäßig das View Skript gerendert, welches den per URL übergebenen Parametern entspricht. Ein Beispiel für eine phtml-Datei gibt es <a href="http://www.educat.hu-berlin.de/doc/phpkurs/">hier</a>.</p>
<p>Das war&#8217;s. Bei Fragen oder Problemen darf gerne ein Kommentar hinterlassen werden. </p>
<p>Weiterlesen: <a href="http://blog.christian-renner.eu/?p=296">Zend Framework &#8211; Tutorial 2. Teil &#8211; Von der Anfrage zum Controller</a></p>
]]></content:encoded>
			<wfw:commentRss>http://christian-renner.eu/development/zend-framework-tutorial-1-teil-hello-world/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>

