FLOW3 auf IIS

Juli 5th, 2009 — 9:05am

Ich habe mir gestern mal die aktuelle Alpha Version des FLOW3 PHP Frameworks heruntergeladen. Mich interessiert vor allem der Dependency Injection Support und wie das Thema Persistence gelöst wurde. Zu beiden existiert ja kaum etwas Brauchbares in der PHP Welt (PHP-Doctrine bislang != brauchbar).

Da mein Laptop mit Windows Vista läuft und ich den eingebauten IIS 7 zum Entwicklen verwende (IIS != XAMPP auf Windows), dachte ich mir schon fast, dass es bei der Verwendung von FLOW3 Probleme geben könnte.

Zunächst einmal musste ich meine PHP Version auf 5.3 aktualisieren (wurde ja erst vor ein paar Tagen released), was sich nicht sonderlich kompliziert gestaltete. Wichtig/neu ist dabei die Pflicht-Einstellung date.timezone in der PHP ini. Diese muss man auf die gewünschte Zeitzone einstellen, sonst erhält man eine entsprechende Warning. Hier die möglichen Einstellungen: http://de2.php.net/manual/es/timezones.php

Beispiel:

date.timezone = Europe/Berlin

Wer PHP noch gar nicht auf seinem Windows Server installiert hat, findet hier eine sehr gute Anleitung.

Obwohl auf der FLOW3 Seite davon ausgegangen wird, dass man die Applikation in das Document Root Verzeichnis eines virtual hosts packt, habe ich der Einfachheit dafür entschieden, die Testanwendung schlichtweg in das Verzeichnis http://localhost/flow3_test/ zu tun. Im Gegensatz zum Zend Framework funktioniert das auch ohne viel einstellen zu müssen.

Die Welcome Seite kann man dann über http://localhost/flow3_test/Public/ aufrufen. Nicht vergessen, vorher noch die Zugriffsrechte (Schreibrechte) des Verzeichnisses entsprechend zu setzen, da FLOW3 fleißig Cache Files schreibt.

Beim Aufruf der o. g. URL wurde ich erstmal von einem 404 Not Found Error begrüßt. Kein Wunder, leitet doch die Anwendung von http://localhost/flow3_test/Public/ auf http://localhost/flow3_test/Public/flow3/welcome weiter.

Wie bei anderen gängigen MVC Frameworks üblich, sollten Requests für Actions/Controllers auf die index.php umgeleitet werden. Das ist in der .htaccess hinterlegt. Unseren Windows Server interessiert die .htaccess, welche im /Public Verzeichnis der FLOW3 Installation liegt, jedoch nicht allzu sehr.

Glücklicherweise hat Microsoft eine URL Rewrite Erweiterung für IIS 6 & 7 veröffentlicht. Einfach herunterladen, installieren, den Anweisungen folgen und fertig. Dann im gleiche Verzeichnis wie die .htaccess liegt eine Datei namens web.config mit folgendem Inhalt erstellen:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <system.webServer>
    <rewrite>
      <rules>
        <rule>
          <match url="(.*)"/>
          <conditions>
            <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
            <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
          </conditions>
          <action type="Rewrite" url="index.php/{R:1}"/>
        </rule>
      </rules>
    </rewrite>
  </system.webServer>
</configuration>

Dann funktionierts auch mit dem URL Rewriting und beim Aufruf von http://localhost/flow3_test/Public/flow3/welcome sollte eine entsprechende Willkommensseite erscheinen.

Mein erstes FLOW3 Package hab ich auch schon angelegt, weiter bin ich allerdings noch nicht gekommen.

Mein erster Eindruck nach einer kleinen Studie der Sources: so eine Code Qualität hats im PHP Bereich noch selten gegeben. Sehr vielversprechend. Wird allerdings für den gemeinen TYPO3/Typoscript Bastler ein ziemlicher Kulturschock sein, sollte er sich auf FLOW3 einlassen.

Comment » | FLOW3, PHP

Zahl mit führenden Nullen formatieren in C#

Juni 8th, 2009 — 2:38pm

Mit Hilfe von String.Format kann man Zahlen mit führenden Nullen formatieren:

String.Format("Download vom {0:D2}.{1:D2}.{2:D2}", now.Day, now.Month, now.Year);

Der entscheidende Teil ist das “D2″ nach dem Argument-Index.

Ausgabe: Download vom 08.06.2009

Comment » | C#

Module Pattern in JavaScript

Juni 7th, 2009 — 4:37pm

Je weiter man sich mit JavaScript beschäftigt, desto mehr bekommt man mit was für eine interessante und vielseitige Sprache man doch mittlerweile hat. Diese Entwicklung wurde vor allem durch verschiedene JavaScript Frameworks vorangetrieben. Neben den vielen Effekthaschereien, welche Scripaculous und co. mittlerweile bieten, sind es doch vor allem die neuen Ideen und Möglichkeiten des Objekt-orientierten Programmierens, welche JavaScript für mich interessanter gemacht haben.

Im Folgenden stelle ich ein paar Optionen vor, wie man seine Objekte in JavaScript aufbauen kann. Sofern nötig, verwende ich die YAHOO User Interface Library (kurz: YUI) als Framework in den Beispielen.

Der Anfang

Ich denke, wie viele habe ich meine “Karriere” in JavaScript Programmierung mit dem Ansammeln von Funktionen begonnen:

var isClicked;

function foo() {
}

function bar() {
}

Die Probleme, die ich an diesen Ansatz für mich erkannt habe: es gibt zu wenig Struktur, man erkennt nicht, welche Funktionen Teil eines größeren, Ganzen sind und die Abbildung von komplexen JavaScript Abläufen wird sehr unübersichtlich. Außerdem fördert dieser rein Funktionsbasierende Ansatz auch die Verwendung von globalen Variablen, um z. B. den Status von Elementen festzuhalten.
Alles in allem nicht wirklich gut geeignet, es sei den für sehr triviale Anwendungen.

prototype basierende Objekte

Nachdem ich mich eine ganze Zeit lang mit o. g. Ansatz herumgeplagt habe, kam ich recht bald auf eine Art, Programme in JavaScript mittels Objekten zu strukturieren. Der erste Ansatz nutzt die prototype Eigenschaft einer Funktion aus, mit der man eine Art Klasse in JavaScript erstellen kann:

function myClass(foo, bar) {
	// das ist der "Konstruktor".
	// hier kann man die Properties eines Objekts setzen.
	this.foo = foo;
	this.bar = bar;
}

	myClass.prototype.doSomething = function() {
		// eine öffentliche Methode der Klasse
	}

	myClass.prototype.handleRollover= function(x, y) {
		// eine öffentliche Methode der Klasse
	}

//
// Verwendung:
//
var instance = new myClass("arg 1", "arg 2");
instance.doSomething();

Das Ganze ähnelt doch einem “klassischen” Objekt wie aus PHP oder C# bekannt etwas mehr. Zumindest was die Erzeugung mittels new und dem Aufruf von Methoden angeht. Man hat sogar einen Klassen-Konstruktor.

Allerdings ist auch diese Version nicht ohne Nachteile, wie ich im Laufe der Zeit feststellen musste. Zum einen ist die Syntax an sich nicht sonderlich eingängig und erfordert einiges an Tipp-Arbeit. Zum anderen sind alle Methoden einer Klasse öffentlich.

Außerdem ist es beim Hinzufügen von Event Handlern nicht ganz so einfach, den Scope, in dem die Handler Funktion ausgeführt wird, beizubehalten.
Damit eine Handler Funktion im Scope der aktuellen Instanz ausgeführt wird, muss man in der YUI folgendes verwenden:

function myClass() {
	// Hinzufügen des Event Handlers
	// Angeben, in welchem Kontext/Scope der Handler
	// ausgeführt wird (nämlich die Instanz von myClass)
	YAHOO.util.Event.on("link_to_click", "mouseover", myClass.prototype.handleRollover, null, this);
}

	myClass.prototype.handleRollover= function(e) {
		// der Event Handler
	}

Man muss also den kompletten Namen der Methode inklusive des Klassennamens und “prototype” angeben sowie mit “this” eine Referenz auf die Instanz, damit der Handler im richtigen Scope ausgeführt wird. Verwendet man statt dessen eine der folgenden Notationen:

YAHOO.util.Event.addListener(document, "click", myClass.prototype.doSomething);
// oder
YAHOO.util.Event.addListener(document, "click", this.doSomething);

Dann bezieht sich “this” innerhalb der Handlerfunktion auf document statt auf die akuelle Instanz von myClass!

Natürlich kann man das noch etwas anders machen, in dem man eine anonyme Funktion verwendet, welche dann wiederum den eigentlichen Handler aufruft:

function myClass() {
	var self = this;

	YAHOO.util.Event.on("link_to_click", "mouseover", function(e) {
		self.handleRollover(e);
	});
}

	myClass.prototype.handleRollover= function(e) {
		// der Event Handler
	}

Die Referenz auf die aktuelle Instanz wird in “var self” zwischengespeichert, weil sich “this” in der anonymen Funktion weiter unten sonst auf das document Objekt beziehen würde. Haaaack! Gerade bei vielen Event Handlern führt das einfach nur zu unübersichtlichem Code.

“Statische” Klassen

Eine andere Art, wie man in JavaScript eine Form von Klassen bekommen kann, ist die folgende:

var myClass = {
	count: 1,
	increase: function() {
		this.count++;
		alert(this.count);
	}  // <-- hier kein Komma!
};

Die Vorteile sind hier, dass die Notation recht einfach (man darf nur bei der letzten Definition eines Members das Komma nicht setzen) und auch sehr übersichtlich ist.

Jedoch haben wir genauso wie bei der vorhergenden Variante das Problem, den Scope eines Event Handlers beizubehalten. Außerdem kann keine Instanz der Klasse mit "new" erzeugt werden und es gibt auch keinen Konstruktor. Außerdem sind auch hier alle Members public.

Der wichtigste Punkt jedoch ist das Verhalten der "Klasse" an sich. Folgendes Beispiel:

var myClass = {
	count: 1,
	increase: function() {
		this.count++;
		alert(this.count);
	}
};

var instance = myClass;
instance.increase();

var instance2 = myClass;
instance2.increase();

Zunächst erwartetes Ergebnis von mir, bevor ich es ausprobierte:

Ausgabe von "2"
Ausgabe von "2"

Tatsächliches Ergebnis:

Ausgabe von "2"
Ausgabe von "3"

Die "Instanz" der Klasse ist also jedes mal exakt die Gleiche.

Nicht unbedingt schlecht. Wenn man diese Art von Verhalten erwartet bzw. braucht, z. B. für einen Cache o. ä. dann ist es sogar sehr gut, wenn man sich dieses statische Verhalten des Objekts zu Nutze machen kann.

Im Prinzip ist die Notation von var myClass = { ... } auch keine Definition einer Klasse, sondern die beiden geschweiften Klammern erzeugen bereits ein neues Objekt. var myClass = { ... } ist eigentlich nichts anderes als var myClass = new Object();

Somit erklärt sich auch dieses auf den ersten Blick vielleicht etwas verwirrende Verhalten.

Das Module Pattern

Das Module Pattern ist mein derzeit favorisiertes Muster, wie ich meine Objekte in JavaScript aufbaue. Letztlich ist es fast eine Mischung aus dem Ansatz, die prototype Eigenschaft einer function zu verwenden und der statischen Klasse aus dem vorherigen Abschnitt. Hier ein kurzes Beispiel:

var myClass = (function(aFoo) { // ein Konstruktor Argument
	// setzen von privaten Eigenschaften
	var foo = aFoo;

	function doSomething() {
		// eine öffentliche Methode
	}	

	function somePrivateFunction() {
		// eine private Methode
	}

	// "Veröffentlichen" von Membern im Rückgabewert
	return {
		doSomething: doSomething
	};
});

//
// Verwendung
//

var instance = new myClass();
instance.doSomething();

Die Vorteile bei dieser Art der Klassendefinition sind doch zahlreich. Es kann eine Instanz mittels "new" erzeugt werden und somit hat man auch die Möglichkeit einen Konstruktor mit Parametern zu nutzen. Es können private Member definiert werden, die nicht von außen aufrufbar sind. Und das definieren von Event Handler Methoden geht sehr einfach von der Hand, ohne dass der Scope des Handlers falsch gesetzt wird:

var myClass = (function() {
	// Hinzufügen des Event Listeners
	YAHOO.util.Event.addListener("link_to_click", "click", eventHandler); 

	function eventHandler(e) {
		// Event Handler
	}	

	// ...
});

Aber wie genau wird das Module Pattern definiert? Hier nochmal die Einzelteile:

Zunächst einmal ist die Klasse eigentlich nichts anderes als eine function mit Rückgabewert:

var myClass = (function(aFoo) {

	// ...

	return {
	};
});

Die Variablen aFoo wäre in dem Fall ein Konstruktorargument.

Alle Variablen, die innerhalb der äußeren Funktion definiert sind, kann man als Eigenschaften des Objekts verwenden:

var myClass = (function(aFoo) {
	// Setzen der Eigenschaft "foo"
	var foo = aFoo;

	function somePrivateFunction() {
		// Diese Eigenschaft ist aus allen Methoden zugänglich
		// ohne "this." zu verwenden.
		alert(foo);
	}

	return {
	};
});

Alle Methoden und Eigenschaften innerhalb dieser äußeren function sind zunächst einmal privat und können nicht von außen aufgerufen werden:

var myClass = (function(aFoo) {

	function doSomething() {
		// diese Methode ist noch privat
	}

	function somePrivateFunction() {
		// diese Methode ist noch privat
	}

	return {
	};
});

Aber mit Hilfe des Rückgabewerts der äußeren Funktion kann man Members "veröffentlichen":

var myClass = (function(aFoo) {

	function doSomething() {
		// diese Methode ist nicht mehr privat!
	}

	return {
		doSomething: doSomething // hier wird die Methode "veröffentlicht"
	};
});

Ein kleiner Kniff, der hilfreich ist, wenn man ein Module Pattern nicht mittels des "new" Operators erzeugen möchte:

var myInstance = (function() {
	// ...
})(); 	// man beachte die () !

Somit wird sofort eine Instanz erzeugt und in myInstance gespeichert - eine Art von statischer Klasse!

Selbstverständlich hat dieses Pattern nicht nur Vorteile. Ein Nachteil ist z. B., dass man Methoden, die öffentlich sein sollen, nochmal im Rückgabewert referenzieren muss.

Dies könnte man wie folgt vermeiden, in dem man die betreffende Funktion einfach inline in den Rückgabewert miteinbezieht:

var myClass = (function(aFoo) {
	var foo = aFoo;

	return {
		doSomething: function() {
			// ...
		}
	};
});

Dieser Fix allerdings bringt das Problem mit sich, dass die Methode nicht mehr von anderer Stelle innerhalb der Klasse aufgerufen werden kann und sieht meiner Meinung nach auch nicht sehr "sauber" aus. Daher vermeide ich die Rückgabe von inline-Methods.

Ein weiterer Nachteil am Module Pattern: der Anblick von umfangreichen Modules ist schon etwas irritieren, sofern man nicht damit gewohnt ist mit diesem Muster zu arbeiten.

Fazit

Trotz unbestrittener Nachteile ist das Module Pattern für mich die derzeit beste Art, Klassen in JavaScript zu emulieren. Es verbindet die Vorteile der verschiedenen Ansätze unter Ausnutzung der Möglichkeiten von JavaScript. Es gibt Kritiker dieses Musters, allerdings konnte ich bisher auch keinen finden, der mir eine wesentlich bessere Alternative aufzeigen konnte, die nicht auch ihre Probleme hätte.

Weitere Informationen:

Comment » | JavaScript

Assembly Durcheinander am Sonntag…

Juni 7th, 2009 — 8:39am

Der erste Blogeintrag dient vor allem mich daran zu erinnern, heruntergeladene Assemblies bzw. meine Downloads im Allgemeinen besser zu organisieren.

Gerade eben habe ich an einem Projekt weitergearbeitet, welches ich von der Arbeit mit nach Hause gebracht habe. Das Projekt verwendet Spring.NET als Dependency Injection Framework. Nun wollte ich noch AOP Funktionalität hinzufügen.

In der Arbeit hatte ich schon eine Referenz auf Spring.Core.dll bei den Verweisen in Visual Studio hinzugefügt. Um die AOP Funktionen nutzen zu können, fehlte noch ein Spring.Aop.dll. Soweit so gut. Für Spring.Core.dll verwende ich die Assembly Version aus der latest stable Version 1.2. Auf meinem Laptop habe ich derzeit nur den Spring 1.2 RC 1, welche ich schon seit längerem installiert hatte. Also dachte ich “spring ist spring“, und fügte eine Referenz auf die Spring.Aop.dll des RC hinzu.

spring_net_no_downloadDas Ergebnis: die AOP Funktionalität funktionierte nicht wie gewohnt. Es gab nur die sehr unverständliche Exception, dass der Typ “Spring.Aop.Framework.ProxyFactoryObject” (!) nicht aufgelöst werden konnte. Erst als ich alle Assembly Verweise auf die Dateien des RC umgestellt hatte, war das Problem behoben. Unglücklicherweise ist im Moment die aktuelle Spring.NET Version 1.2 stable nicht zum Download vorhanden (warum auch immer). Siehe Screenshot auf der linken Seite.

Visual Studio brachte mich schließlich auf die richtige Spur, da bei Assembly Versionsunterschieden eine Warnung generiert wird. Im ersten Moment jedoch nahm ich diese Warnung gar nicht wahr, weil ich annahm bei der Implementierung des Advices in der App.Config XML Datei etwas falsch gemacht zu haben. Ja, ich sollte mehr Vertrauen in Visual Studio haben…

Wird Zeit, dass ich alle Downloads, die für die Entwicklung relevant sind evtl. zentral auf meinem Server ablege. So wäre sowohl von meinem Labtop als auch von meinem Desktop PC daheim und in der Agentur alle wichtigen Dateien zu erreichen.

Comment » | C#, Visual Studio

Back to top