7.7 Datenbankverbindung professionell
Natürlich wollen wir die Datenbankverbindung in eine Klasse auslagern. Klassen, die für eine Verbindung mit einer Datenbank stehen, kann man gut mit dem Wort "Repository" kennzeichnen. Wir erstellen uns also eine Klasse StudentRepository
.
Wenn wir im Unterkapitel Klassen in Dateien auslagern und MVC-Prinzip nachsehen, dann wurde dort das MVC-Prinzip erläutert. Dieses MVC-Prinzip wollen wir hier durch ein Repository ergänzen.
Was wir eben in einer Datei index.php
hatten, wird nun in drei Dateien aufgeteilt.
index.php
index.php
ist das Hauptprogramm und muss mit require_once
die anderen Dateien einbinden. Anschließend kommen die Variablen und die Verbindung zur Datenbank. Bis Zeile 10 entspricht es dem bekannten Sourcecode aus dem letzten Unterkapitel.
Datei index.php (nur erste Zeilen)
In Zeile 14 erstellen wir ein Objekt der (noch neu zu erstellenden Klasse) StudentRepository
und müssen der Klasse das Datenbankobjekt $pdo
übergeben, damit eine Verbindung zur Datenbank vorhanden ist.
In Zeile 15 rufen wir die Methode fetchStudentByMatNr()
auf, die dann die eigentliche Datenbankabfrage enthalten wird.
StudentRepository.php
StudentRepository.php
führt die Datenbankabfrage durch. Die Datenbankabfrage haben wir in eine Methode fetchStudentByMatnr()
geschrieben. Sicherlich würden in einem realen Projekt einige weitere Abfragen hinzukommen, die man dann alle in eigene Methoden schreiben kann.
Datei StudentRepository.php
In Repository-Klassen finden "echte" Datenbankabfragen statt. Aber oftmals möchte man Datenbankabfragen noch bearbeiten, z.B. um Teilbereiche zu bekommen. Wir haben in unserer Datenbanktabelle z.B. Vorname und Nachname in einem Feld (sollte man nicht machen!) und wollen nun jeweils die Vornamen auslesen. Hierfür ist eine Model-Klasse gut, die die Datenbankabfragen um "virtuelle Abfragen" ergänzen kann. Mit der Model-Klasse werden also Datenbankstrukturen sinnvoll erweitert, ohne dass redundante Daten in der Datenbank gespeichert werden müssen.
StudentRepository.php
enthält als Eigenschaften ($id
, $name
, $matnr
, $semester
und $course
) alle Spalten der Datenbank (id, name, matnr, semester und course), sowie weitere Eigenschaften, die über Methoden gefüllt werden. In unserem Fall wird mittels regulärem Ausdruck aus dem Gesamtnamen der Vorname ermittelt.
StudentModel.php
StudentModel.php (fertig)
Daten von StudentRepository an StudentModel übergeben
Wir wollen später in der index.php
mit Objekten arbeiten und nicht mit Arrays. Dies hat in der professionellen Programmierung viele Vorteile.
Datei StudentRepository.php (vollständig, aber noch vorläufig)
Die Ausgabe auf dem Browser:
- Bis Zeile 19 kennen wir die Datei schon (siehe oben).
- In Zeile 24 nutzen wir die PDO-Methode
fetch()
, die uns die erste Zeile des Ergebnisses in ein Array liefert. - In Zeile 26 wird die Klasse
StudentModel
instanziert, sodass z.B. mit$student->id
auf die Eigenschaften zugegriffen werden kann. - In Zeilen 27 - 31 werden alle Eigenschaften "gefüllt".
- In Zeilen 33 - 35 wird das Objekt
$student
ausgegeben. Es kann erkannt werden, dass es sich wirklich um ein Objekt handelt.
Somit kann jetzt in der index.php
ein Datenbankeintrag mit z.B. $student->name
angesprochen werden.
Anmerkung
Sie können sich immer mal wieder mit print_r()
oder var_dump()
vergewissern, was Sie gerade in Variablen haben! An der Ausgabe oben können Sie sehen, dass das HTML-Tag <pre>
hierfür sehr hilfreich sein kann. Vergessen Sie aber diese Befehle nicht im Quellcode wieer zu löschen, da es zu Fehlern bei der Ausgabe von HTML und HTTP Headern kommen kann.
StudentRepository.php
Nun kommt einen weitere Verbesserung: In der Datei StudentRepository.php hatten wir die Eigenschaften der Klasse StudentModel alle einzeln gefüllt. Mit PDO-Methoden können wir dies automatisch erledigen, sodass der finale Sourcecode dann wie folgt aussieht:
Datei StudentRepository.php (fertig)
Die Ausgabe auf dem Browser:
Bis Zeile 21 kennen wir die Datei schon (siehe oben).
Mit fetch()
hatten wir nur den ersten Eintrag bekommen. Mit fetchAll()
in Zeile 27 erhalten wir nun alle abgefragten Datenbankeinträge.
Die PDO-Methoden setFetchMode()
in Zeile 26 und fetchAll()
in Zeile 27 benötigen als Parameter PDO::FETCH_CLASS
und die Zielklasse StudentModel
. PDO::FETCH_CLASS
ist eine PDO-Konstante für die Datenformatierung.
Zwei weitere Dinge sind bemerkenswert:
- Wir haben ein Objekt
$student
der KlasseStudentModel
, das direkt über den Aufruf vonsetFetchMode()
erstellt wurde. Die Zeile$student = new StudentModel()
ist somit nicht mehr notwendig. - Wir haben nun ein indiziertes Array
$student
und die einzelnen Einträge im Array sind Objekte, jeweils ein Objekt für eine (Ergebnis-)Zeile der Datenbank.
index.php
index.php (fertig)
Die Ausgabe auf dem Browser:
Sie haben hier mehrere Dinge gelernt
- Die Datenbankverbindung wird im Hauptprogramm erstellt (hier: Objekt
$pdo
). - Das Objekt
$pdo
wird an die Repository-Klasse (hier: StudentRepository) weitergegeben und die Datenbankabfrage in einer Methode (hier:fetchStudentByMatNr()
) ausgeführt. - Anschließend wird das Ergebnis der Datenbankabfrage an die Model-Klasse (hier: StudentModel) weitergereicht. Dazu wird ein Objekt der Model-Klasse erstellt oder aber eine PDO-Methode erstellt dieses Objekt automatisch.
- Dadurch, dass dem Repository sowohl die Objekte der Klasse PDO als auch die Model-Klasse bekannt sind, kann man im Hauptprogramm auf die Zeilen- und Spalteneinträge der Datenbankergebnisse zugreifen (z.B.
$student[1]->course
).
Hier können Sie eine Zip-Datei herunterladen, die den gesamten Sourcecode enthält. Sie sollten das Programm unbedingt auf Ihrem Server installieren und ausprobieren: StudentDatabaseRequest.zip.
Übung
Angenommen Sie müssen eine neue Spalte in der Datenbank hinzufügen (z.B. das Datum der Immatrikulation). An welchen Stellen müssen Sie den Sourcecode anpassen?
Lösung
Damit alles so funktioniert wie vorher, müssen Sie lediglich in der Datei StudentModel.php
eine Eigenschaft hinzufügen, die genauso heißt, wie die Datenbankspalte. Damit ist die Art der Programmierung schon recht gut erweiterbar.