Artikel
von Patrick Froch
Anspruch 3/5 Fat Free Framework 3.x PHP 5.6
Eine wesentliche Aufgabe eines PHP-Frameworks ist der Umgang mit Datenbanken. Hier gibt es die verschiedensten Möglichkeiten, von nativem SQL, über Query-Builder bis hin zu objektorientierten Klassen. In diesem Artikel werde ich auf die verschiedenen Möglichkeiten eingehen, die das Fat Free Framework bietet.

Verbindung aufbauen

Auch wenn F3 verschiedene Datenbanken unterstützt, werde ich hier nur auf MySQL eingehen. Der Verbindungsaufbau ist ganz einfach.

Natives SQL

Die einfachste Möglichkeit eine Abfrage abzusetzen, ist natives SQL. Das Resultat kann auch gleich einer Variable zugewiesen und in einem Template genutzt werden. Neben einzelnen Abfragen, sind auch Transactions möglich.

Parameter

Da das direkte Einfügen von Parametern in Abfragen einige Gefahren birgt, unterstützt F3 das parametrisieren von Abfragen. Die Parameter können auch benannt werden.

Logging

Will man sich alle Abfragen anzeigen lassen, bietet F3 die Methode log().

Objektorientiert

Um nicht ständig SQL schreiben zu müssen, kann man auf die Mapper zurückgreifen. Man benötigt zuerst eine Instanz der entsprechenden Tabelle. Im Beispiel wird die Tabelle users verwendet.

Laden

Nun haben wir ein Objekt der Tabelle users. Es enthält noch keine Daten, aber bereits alle nötigen Methoden und es kennt die Struktur der Tabelle. Um es nun mit Daten zu füllen, kann man z.B. einen Datensatz aus der Datenbank laden. Nun kann man mit $user->userID auf die Daten des Datensatzes zugreifen. Natürlich funktionieren statt userID alle Felder der Tabelle. Oft ist es nötig vor der Verwendung zu prüfen, ob das Objekt überhaupt Daten enthält.

Erstellen

Will man einen neuen Datensatz erstellen ist dies genauso einfach. Man kann genauso einen Datensatz laden, ihn verändern und dann die save()-Methode aufrufen. Der Unterschied ist, dass dann ein Update statt eines Inserts gemacht wird.

Zurücksetzen

Enthält das Objekt bereits Daten und man möchte einen neuen Datensatz erstellen, muss man das Objekt erst zurücksetzen. Dies geschieht mit reset().

Löschen

Um einen Datensatz zu löschen, gibt es die erase()-Methode.

Direkte Datenübernahme

Es ist möglich, Daten z.B. direkt aus dem $_POST-Array zu übernehmen. Will man ein Formular mit Daten aus der Tabelle versehen, funktioniert der Weg auch anders herum. Nun kann im Template über das $_POST-Array auf die Daten zugegriffen werden. Man hat also eine einheitliche Methode, egal ob das Formular einen Fehler hat und mit den Werten neu gerendert werden muss, oder ob die Daten aus der Datenbank kommen.

Ergebnismengen

Normalerweise wird beim Laden eines Datensatzes immer nur ein Datensatz geladen. Will man die Einträge einer Ergebnismenge nach einander verarbeiten, kann man sie mittels skip() durchlaufen. Da skip() bereits beim ersten Aufruf einen Datensatz weiter springt, kann man in diesem Fall keine while()-Schleife verwenden und muss auf do-while ausweichen. Ich finde dies etwas gewöhnungsbedürftig.

Ergebnis als Array

Besser finde ich persönlich die find()-Methode. Sie funktioniert wie load(), gibt aber ein Array von Mapper-Objekten zurück, über das normal iteriert werden kann.

Alles auslesen

Will man alle Elemente einer Tabelle erhalten, übergibt man der find()- oder load()-Methode keine Werte.

In Array umwandeln

Will man ein Mapper-Objekt in ein assoziatives Array umwandeln, nutzt man cast().

Order, Offset und Limit

Die load()- und die find()-Methode nehmen als zweiten Parameter ein Array mit Einstellungen für Order, Offset und Limit entgegen.

Paginierung

Ein weiterer Weg Ergebnimengen aufzuteilen ist paginate(). In diesem Beispiel lädt F3 die Datensätze, die visits>3 entsprechen und gibt jeweils 5 zurück. Das Rückgabe-Array ist wie folgt aufgebaut:
  • [subset] array of mapper objects that match the criteria
  • [count] number of of subsets available
  • [pos] actual subset position
Da man die Anzahl der Seiten erst nach dem ersten Aufruf erhält, ist mir leider nicht klar wie man dies ohne doppelten Aufruf der ersten Abfrage sinnvoll nutzen soll. Die einzige Möglichkeit, die ich gefunden habe, ist nicht gerade elegant:

Operationen mit Feldern

In F3 ist es möglich "virtuelle Felder" zu erstellen, dies meint Felder, die nicht in der Datenbank stehen und erst in der Applikation erstellt werden. Im diesem Beispiel wird das Feld totalprice erst zur Laufzeit erstellt und berechnet. Es enthällt die manuelle Berechnung für jeden einzelnen Datensatz, beim Durchlaufen der Ergebnismenge. Noch viel interessanter ist das Laden von Daten aus einer anderen Tabelle: Hier wird der Name eines Lieferanten aus der Tabelle suppliers in die Ergebnisse der Produkttabelle (products) eingefügt. Wichtig ist, dass die virtuellen Felder vor dem Laden der Daten definiert werden müssen!

Fazit

Ich finde die Lösung sehr gelungen, vor allem da keine Objekterstellung oder Konfiguration nötig ist. Im Gegensatz zu anderen DBAL funktioniert es out-of-the-box.

Zurück

Kommentare

Aufgrund der unklaren Rechtslage durch die DSGV habe ich mich entschlossen, die Kommentare bis auf Weiteres zu deaktivieren.