dedlfix: Dynamische Datenbankschnittstelle

Beitrag lesen

echo $begrüßung;

ich studiere technische Informatik und muss nun für das Wahlpflichtfach Webdesign eine Datenbankschnittstelle mit PHP entwickeln. Allerdings habe ich diese Woche das erste Mal seit 3, 4 Jahren wieder was mit PHP programmiert und bin somit wohl wieder ein Anfänger.

Aktuelle PHP-Versionen enthalten PDO, das das gleiche Zeil verfolgt. Macht aber nichts, du sollst es ja zu Übungszwecken neu erfinden.

Die Datenbankschnittstelle soll in einem Webprojekt verwendet werden und auf MySQL basieren. Diese Datenbankschnittstelle soll gegen eine andere getauscht werden können (beispielsweise eine die MS SQL Server unterstütz) ohne am Quellcode etwas verändern zu müssen.

Dieser Wunsch bietet in meinen Augen nur den einen genannten Vorteil, hat aber mit einigen nicht unerheblichen Nachteilen zu leben. Beispielsweise ist man damit auch auf einen minimalen SQL-Wortschatz beschränkt und kann spezielle Leistungsmerkmale, Funktionen und Statements der zugrunde liegenden DBMS nicht ausnutzen. Teilweise sind auch Funktionalitäten in den verschiedenen DBMS nicht kompatibel zueinander. Während MySQL auto_increment kennt, muss man bei Oracle Sequenzen verwenden, usw. usf. Auf der anderen Seite steht der ziemlich selten auftretende Fall eines DBMS-Wechsels.

Nach meiner Erfahrung ist es besser keine Schnittstelle zu einem DBMS zu implementieren sondern eine zu den Daten. Das heißt, die Anwendung fragt nach Daten und übergibt solche. Wo diese herkommen bzw. hingehen, interessiert die Anwendung nicht weiter. Sie muss sich nicht mit SQL-Statements und dergleichen rumschlagen. Selbst ob überhaupt ein DBMS dahintersteckt, kann ihr egal sein.
Die Daten-Schicht kann ihrerseits auf die volle Funktionalität eines speziellen DBMS zugreifen. Auch proprietäre SQL-Bestandteile können Verwendung finden. Auch mehrere (auch verschiedene) DBMS oder andere Datenhaltungen (XML, Dateien) können Anwendung finden.

Aber das nur nebenbei, du hast ja deine Übungsaufgabe.

Diese Datenbankschnittstelle soll darüber hinaus Objektorientiert sein, soll eine vernünftige Fehlerbehandlung enthalten und soll so "gut" wie möglich programmiert werden, denn schließlich wird diese ja auch von meinem Professor bewertet. Den folgenden Code habe ich bisher mal entwickelt:

Und was ist nun deine Frage? Soll ich Anmerkungen zu deinem Code geben?

/*************** abstrakte Datenbank Schnittstelle ***************/

<?php

abstract class DatabaseConnection
   {
      # Protected Variablen

Das diese protected sind sieht man. Wenn du was kommentieren willst, kommentiere den Sinn, der hinter einem bestimmten Ding steht, nicht das aus dem Quelltext offensichtliche.

protected $connection = NULL;
      protected $host = NULL;
      protected $database = NULL;
      protected $user = NULL;
      protected $password = NULL;

# Abstrakte Funktionen, Definitionen
      public abstract function Connect($host, $user, $password);

An welcher Stelle wird der Wert für $database übergeben? Einige DBMS (bzw. DBMS-APIs) benötigen sie bereits beim Verbinden, andere erst später. Für erstere muss, für letzere sollte das Auswählen der Datenbank ebenfalls in Connect() erfolgen, der Einheitlichkeit wegen.

Warum merkst du dir überhaupt Host, Username und Password, wenn sie Pflichtparameter bei Connect() sind und ansonsten (vermutlich) nicht weiter gebraucht werden?

$this->connection = @mysql_connect($host, $user, $password, true);

Wenn du schon ein modernes PHP voraussetzt, solltest du auch gleich auf die modernere mysqli-Extension verwenden. (Lass dich nicht von der "Experimentell"-Warnung in der deutschen Übersetzung irreführen, die gilt schon seit langem nicht mehr.)

if ($this->connection == false)
         {
            $exception = new DatabaseConnectionException($host, $user, $password);
            throw $exception;

Wozu die extra Variable? Du brauchst sie nicht weiter, kannst also "throw new Exception..." als Einzeiler notieren.

class DatabaseConnectionException extends ExtendedException
   {
      public function __construct($host, $user, $password)
      {
         if (!$this->showPassword) $password = "*****";

Befindet sich eine Definition (Deklaration plus Wertzuweisung) von $this->showPassword in ExtendedException? Wenn ja, kannst du daraus auch eine (Klassen-)Konstante machen, denn man hat sowieso keine Chance, den Wert während der Laufzeit zu ändern. Jedenfalls nicht so, wie du das derzeit notiert hast.

$this->message = "Fehler beim Herstellen der Datenbankverbindung" . ZEILENUMBRUCH .
                          "Host: " . $host . $this->ZEILENUMBRUCH .
                          "User: " . $user . ZEILENUMBRUCH .
                          "Password: " . $password;

ZEILENUMBRUCH einmal mit, einmal ohne $this-> ? Außerdem ist es der einzige deutsche Bezeichner unter ansonsten englischen. Ich plädiere für einsprachige Bezeichner.

Für wen ist eigentlich der Meldungstext gedacht? Der Endanwender kann mit den Informationen nichts anfangen, und der Systemadministrator hat sowieso Zugriff auf das Passwort.

?>

Dieser Abschluss ist am Dateiende nicht nötig. Setzt man ihn, muss man achtgeben, keine Whitespace-Zeichen dahinter stehen zu lassen. Lässt man ihn weg, missfällt das zwar der Ordnungsliebe einiger, man hat aber eine "headers already sent"-Fehlerquelle weniger.

echo "$verabschiedung $name";