Entwicklung eines Kommentarsystems mit PHP: 2. Datenbankklasse

Nachdem wir die Planungsphase nun abgeschlossen haben, fangen wir nun endlich auch mal an zu programmieren. Und zwar kümmern wir uns heute um die Datenbankklasse. Das ist die Klasse die sich um alle Datenbankoperationen kümmert, also verbinden mit Datenbank, Query ausführen, Ergebnis bekommen…

Klassenarchitektur

Die Klassenarchitektur, bezeichnet die Anordnung der Klasse im gesamten System aber auch, welche Funktionen die Klasse enthält.

Grundsätzlich brauchen wir nur relativ wenig Funktionen. Der Grund dafür ist das wir versuchen die DB-Klasse simpel zuhalten. Um später nicht zuviel unnötigen Code zu haben.

Ich habe bereits kurz geplant welche Funktionen wir alle brauchen:

Funktionen der DB-Klasse

Wir werden jetzt einzeln alle Funktionen programmieren und danach alles zu einer Klasse zusammenschieben. Dabei möchte ich auf jede Funktion einzeln eingehen. Ich werde soweit wie möglich sprechende Variablennamen verwenden und dann auch nicht mehr explizit auf deren Funktion eingehen.

connect()

Diese Funktion macht nichts anderes als sich mit der Datenbank zu verbinden und die zugehörige Tabelle auszuwählen.
Wir benutzen dafür die Befehle mysql_connect() und mysql_select_db(). Diese brauchen relativ viele Parameter um richtig zu funktionieren.

function connect($db_host, $db_username, $db_password, $db_name) {
	mysql_connect($db_host, $db_username, $db_password) or die('Konnte nicht mit Datenbankserver verbinden!');
    mysql_select_db($db_name) or die('Datenbank konnte nicht ausgewät werden.');
}

error()

Bei SQL können leicht Fehler passieren und so möchten wir eine kleiner Fehlerfunktion einbauen. Diese Funktion beendet zu erst das gesamte Skript mit exit() und gibt dann einerseits den Fehler aus den MySQL entdeckt hat, aber auch direkt den ganzen Query, so kann man den Fehler schneller finden.

function error($sql) {
      exit('MySQL Fehler: '.  mysql_error().'Die SQL Anweisung lautete:<i>'. 
           htmlspecialchars($sql).'</i>');
    }

chars()

Die Funktion chars() ist einer der einfachsten Funktionen in der Datenbankklasse. Sie ist quasi nur eine Kurzform für die MySQL-Funktion mysql_real_escape_string(). Für alle die es nicht wissen: Diese Funktion bereitet Text für den Eintrag in die Datenbank auf, d. h. Anführungszeichen wie “ werden escaped, und und und

function chars($string) {
      return mysql_real_escape_string($string);
        
    }

query()

Nach der einfachsten Funktion, kommen wir nun zu schwersten Funktion. Die query() Funktion führt eine MySQL Anweisung aus und gibt je nach Anweisung ein Ergebnis zurück. Nun aber zum Code, zuerst prüfen wir ob das Ergebnis des Querys das wir in die Variable $result geschrieben haben, falsch ist und somit kein MySQL Object. Wenn dies zutrifft führen wir unsere eigene error()-Funktion aus und füttern sie mit der SQL-Anweisung. Mit dem @-Zeichen unterdrücken wir das mysql_query() das Skript direkt abbricht und übernehmen die Fehlerbehandlug selbst.

Sollte das Resultat der Anweisung ein MySQL Object sein, geben wir dieses einfach zurück.

function query($sql) {
      if (($result = @mysql_query($sql)) === false){
          error($sql);
      }
        
      return $result;
    }

fetch_array()

Und auch die letzte Funktion ist eigentlich nur eine Kurzform für die MySQL Funktion mysql_fetch_assoc(). Diese konvertiert das MySQL Ergebnis (MySQL Object) in einen assoziativen Array auf den wir dann zugreifen können.

Umbau der Funktionensammlung zur Klasse

Jetzt haben wir alle nötigen Funktionen programmiert und können nun damit anfangen das alles in eine Klasse umzuwandeln. Dafür setzten wir zuerst das Gerüst um alle Funktionen: class mysql {...} Das Keyword class leitet eine Klasse ein, darauf folgt der Name. Dazwischen stehen dann alle Methoden dieser Klasse.

Doch noch sind wir nicht fertig. Jetzt muss für alle Funktionen noch deren Sichtbarkeit definiert werden. Es gibt hier 3 verschiedene Stufen:

  • public, jeder und jede andere Klasse kann darauf zugreifen
  • private, nur die eigene und vererbte Klassen können darauf zugreifen
  • protected, nur die eigen kann darauf zugreifen

Wir vergeben unseren Funktionen folgende Sichtbarkeiten.

  • error() => private (wird nur von der Query-Funktion benutzt)
  • chars()> => public (wird von allen späteren Klassen benutzt)
  • query()> => public (wird von allen späteren Klassen benutzt)
  • fetch_array()> => public (wird von allen späteren Klassen benutzt)

Die letzte kleine Änderung nehmen wir noch bei der Funkion query() vor. Dort benutzen wir die Funktion error(). Damit PHP weiß, wo sich diese Funktion befinden wird aus dem einfachen Funktionsaufruf this->error(), dadurch weiß PHP das die Funktion in derselben Klasse definiert ist wo sie auch aufgerufen wurde.

Jetzt können wir unsere Klasse mit diesem Code initialisieren und der Variable $sql zuordnen.

$db = new mysql();

Doch bis jetzt müssen wir danach noch die Funktion connect() aufrufen, welche dann die Verbindung herstellt. Dies lässt sich auch direkt bei der Initialisierung lösen. Dafür ersetzen wir connect($db_host, $db_username, $db_password, $db_name) durch __construct($db_host, $db_username, $db_password, $db_name). Dies ist der Konstruktor. Der Konstruktor wird aufgerufen wenn die Klasse initalisert wird, somit müssen wir jetzt bei den Initilsierung noch ein paar Parameter mehr mitgeben. Der vorige Code ändert sich nun in:

$db = new mysql('db.server.de', 'user', 'password', 'kommenta');

Alle Funktionen lassen sich nun so nutzen.

$db->chars('TestText');

Kompletter Code

Ich hoffe euch gefällt auch der zweite Teil. Feedback ist immer gerne gesehen. Im dritten Teil werden wir das Datenbankschema bauen.

Ich bin Kevin, und schreibe hier über Themen die sich von CSS über Designs bis zur testgetriebenen Entwicklung mit PHP erstrecken. Ich arbeite in einer kleinen Firma als PHP-Entwickler und entwickle dort PHP Backends für verschiedene Projekte vorallem mit Laravel. Privat betreibe ich noch diesen Blog und notesafe.

5 Kommentare Schreibe einen Kommentar

  1. Hi!

    Freue mich schon auf deinen nächsten Artikel. Sieht alles professionell aus, vor allem das mit dem Whiteboard!

    Warum schreibst du nicht public, private oder protected zwischen function und dem Funktionsnamen?

    • Vielen Dank.

      Man darf die Zugriffsbeschränkungen doch gar nicht zwischen function und dem Namen, schreiben. Die müssen doch immer am Anfang stehen. Oder meintest du das ich sie beim ersten Codebeispiel weggelassen habe?

      Grüße
      Kevin

Schreibe einen Kommentar zu Kevin Antworten abbrechen