6.3 Die Database-Komponente 

Die Database-Komponente besteht aus zwei Teilen. Auf der einen Seite stehen die Backend-Handler, welche auf PDO aufsetzen und eine einheitliche API zum Zugriff bieten, DSN-Strings parsen, um eine Verbindung aufzubauen, und verschachtelte Transaktionen ermöglichen. Dazu bieten die Handler Factory-Methoden für den Query-Builder an, den zweiten Teil der Komponente.
| Das Factory-Pattern |
|
Das Factory-Entwurfsmuster wird in der deutschen Literatur gerne ins Deutsche übersetzt, weil die Vorstellung einer Fabrik den beschriebenen Mechanismus sehr gut illustriert. |
|
Das Factory-Pattern beschreibt eine zentrale Klasse, die abhängig von Übergaben oder der Umgebung Objekte produziert. Meistens wird dies über eine statische Methode realisiert, die – abhängig von den übergebenen Parametern – ein Objekt einer bestimmten Klasse instanziiert und zurückgibt. |
|
Im Falle von Database wird abhängig vom RDBMS im DSN ein Objekt einer Klasse, die von ezcDbHandler ableitet, erzeugt, welche Spezifika des gewählten RDBMS berücksichtigt. |
Der Query-Builder auf der anderen Seite bietet eine objektorientierte API an, um SQL-Abfragen zu generieren und dabei die Spezifika des verwendeten RDBMS zu beachten. Dadurch, dass der Programmierer keine SQL-Strings mehr selbst schreiben muss, hilft die Komponente, Syntaxfehler zu vermeiden. Die semantischen und logischen Unterschiede der SQL-Dialekte werden durch RDBMS-spezifische Implementierungen vor dem Entwickler verborgen.
6.3.1 PDO 

Dieser Abschnitt soll Ihnen eine kurze Einführung in PDO bieten, mit einer Beschreibung der konkreten Zusammenhänge zur Database-Komponente. Die PHP-Extension PDO registriert drei Klassen in PHP, über die Sie auf Datenbanken zugreifen können:
- PDO Die Klasse PDO selbst baut die Verbindung auf, stellt Methoden zum Start von Transaktionen bereit und bietet Zugriff auf verschiedene Informationen, wie die Liste der verfügbaren Treiber oder auch die vom RDBMS automatisch generierte ID bei der letzten INSERT-Query. Der ezcDbHandler erweitert diese Klasse und stellt damit die gleichen und weitere, eigene Methoden bereit.
- PDOStatement PDOStatement repräsentiert Anfragen an die Datenbank. Wenn eine Anfrage durch das RDBMS beantwortet wurde, stellt PDOStatement das Ergebnis dar und bietet verschiedene Methoden an, über das Ergebnis zu iterieren. Der Query-Builder der Database-Komponente erzeugt PDOStatements, mit denen Sie entsprechend der Dokumentation von PDO arbeiten können.
- PDOException Die PDOException, abgeleitet von der PHP-Klasse Exception, wird bei fehlgeschlagenen Statements geworfen. Alle anderen Fehler sollten durch diese Komponente abgefangen werden.
6.3.2 Fluent-Interfaces 

Wie bereits erwähnt, baut der Query-Builder auf einer objektorientierten API auf, um SQL-Queries zu erzeugen, ohne dass Sie selbst SQL schreiben müssen. Die Art der bereitgestellten API wird häufig als Fluent-Interface bezeichnet, die nur sehr selten eine Anwendung findet und damit einer kurzen Beschreibung bedarf.
| Operator-Overloading |
|
Als Operator-Overloading bezeichnet man die Möglichkeit, in objektorientierten Sprachen Operatoren wie +, – oder * Methoden auf den eigenen Objekten verwenden zu lassen, um diese Operation durchzuführen. Dadurch werden auch Rechnungen mit komplexen Datentypen ohne komplizierte Verkettung von Methodenaufrufen möglich. Das folgende Beispiel soll verdeutlichen, wie zum Beispiel die Multiplikation von Matrizen zwar mit Objekten und entsprechenden Methoden realisiert wird, durch Operator-Overloading aber in der Anwendung intuitiver wirkt: |
$matrix = $matrixA * $matrixB; |
|
Operator-Overloading ist in PHP mit der PECL-Extension ext/operator (http://pecl.php.net/package/operator) von Sara Golemon möglich. PECL [http://pecl.php.net/ ] ist ein Verzeichnis mit PHP-Erweiterungen, die nicht mehr oder noch nicht im PHP-Kern aufgenommen worden sind. Aufgrund tiefgreifender Eingriffe in zentrale Teile von PHP wird diese Extension jedoch voraussichtlich nie ihren Weg in Standarddistributionen finden. |
Im folgenden Beispiel werden Fluent-Interfaces am Beispiel von Rechnungen mit komplexen Zahlen vorgestellt. [http://de.wikipedia.org/wiki/Komplexe_Zahlen ] Da PHP ohne die PECL-Extension ext/overload im Alpha-Stadium kein Operator-Overloading erlaubt, sind andere Varianten gefragt, um komfortabel mit komplexeren Strukturen zu rechnen. Begonnen wird mit einer simplen Klasse:
class gpComplexNumber
{
public $r;
public $i;
public function __construct( $r, $i = 0 )
{
$this->r = (float) $r;
$this->i = (float) $i;
}
public function __toString()
{
return sprintf( '(%.2f + %.2fi)', $this->r, $this->i );
}
}Listing 6.1 Basisimplementierung
Der Konstruktor initialisiert den Real- und Imaginärteil der komplexen Zahl mit den übergebenen Werten. Um den Beispielcode so kurz wie möglich zu halten, werden die beiden Objekteigenschaften public definiert. Die __toString()-Methode dient seit PHP 5 dazu, eine String-Repräsentation eines Objekts zurückzugeben, wenn es zum Beispiel bei der direkten Ausgabe nach String umgewandelt (gecastet) wird. Ein Fluent-Interface entsteht nun, wenn wir Methoden, die das Objekt manipulieren, die eigene Instanz wieder zurückgeben lassen. Durch die direkte Dereferenzierung von PHP 5 lässt sich bei der Rückgabe einer Methode erneut eine Methode aufrufen. Entsprechend werden zwei Methoden zur Addition und Multiplikation von komplexen Zahlen in die Klasse eingefügt.
public function add( gpComplexNumber $number )
{
$this->r += $number->r;
$this->i += $number->i;
return $this;
}
public function mul( gpComplexNumber $number )
{
$r = $this->r * $number->r + $this->i * $number->i;
$i = $this->r * $number->i + $this->i * $number->r;
$this->r = $r;
$this->i = $i;
return $this;
}Listing 6.2 Methoden zur direkten Dereferenzierung
Die Funktionen akzeptieren als einzigen Parameter eine weitere komplexe Zahl, führen die entsprechende Rechnung aus und geben anschließend das manipulierte Zahl-Objekt, auf dem sie aufgerufen wurden, zurück. Damit sind verkettete Aufrufe für komplexe Berechnungen einfach und übersichtlich möglich:
$a = new gpComplexNumber( –1, 2 );
$b = new gpComplexNumber( –3, 2 );
// ( $a + $b * (2 – 3i) ) * 2
echo $a->add( $b->mul( new gpComplexNumber( 2, –3 ) ) )
->mul( new gpComplexNumber( 2 ) );
// Ausgabe: (-26.00 + 30.00i)Listing 6.3 Verwendung der Klasse
Als Erstes werden zwei komplexe Zahlen, jeweils mit Real- und Imaginärteil erzeugt. Mit diesen Zahlen und zwei weiteren, die direkt im Laufe der Rechnung erzeugt werden, wird dann die Rechnung ($a + $b * (2 – 3i)) * 2 ausgeführt. Dazu wird zunächst auf dem Objekt $a die Methode add() mit dem Produkt von $b und der komplexen Zahl 2 – 3i aufgerufen. Die Methode gibt nach dem Ausführen der Rechnung mit $this das Resultat dieser Rechnung zurück. Das Resultat lässt sich nun direkt weiterverwenden, indem die nächste Methode darauf ausgeführt wird – im obigen Beispiel ist dies die Multiplikation mit 2. Die letztendliche Ausgabe der resultierenden Zahl über die Konvertierung durch __to String() führt zu dem erwarteten Ergebnis –26 + 30i.
Es lässt sich darüber streiten, ob Fluent-Interfaces für Rechnungen wirklich sinnvoll sind, da die Klammerung der Teilterme etwas an Übersichtlichkeit verliert. Doch zeigt das Beispiel Ihnen, wie diese generell funktionieren, und spätestens beim Query-Builder wird sich dies als ein sinnvolles Einsatzgebiet zeigen.




Ihre Meinung






