MySQL PHP-Klasse

klausschreiber

Well-known member
ID: 162475
L
6 Mai 2006
247
8
Hallo,

ich habe mir eine PHP-Klasse zur Datenbankabfrage geschrieben. Bei den meisten MySQL-Klassen wird die Datenbankverbindung ja gleich über den Konstruktor aufgebaut und dann (vermutlich) nur in die Dateien eingebunden, die eine Datenbankverbindung benötigen.

Spricht etwas dagegen, die Verbindung erst bei der ersten Abfrage aufzubauen und dann die Datenbankklasse überall (z.B. über eine header.inc.php) einzubinden?

Ist es nicht generell sinnvoller, die Verbindung erst bei der ersten Abfrage einzubauen? Weil es kann ja auch Dateien geben, die nicht bei jedem Aufruf eine MySQL-Verbindung brauchen.

Also statt:
PHP:
public function __construct()
{
    $this->connect();
}
folgendermaßen:
PHP:
public function query($sql)
{
    $this->connect();
    Datenbankabfrage ...
}

private function connect()
{
    if (!$this->connection) {
        $this->connection = @mysql_connect ...
    }
}

Gruß,
Klaus
 
Du hast halt immer eine Abfrage "Hey, bin ich schon verbunden?" und das bei jeder Anfrage an die DB.

Einfacher wäre zu sagen: Wenn ich keine DB brauche, binde ich halt die Klasse einfach nicht ein.
 
ich habe mir eine PHP-Klasse zur Datenbankabfrage geschrieben. Bei den meisten MySQL-Klassen wird die Datenbankverbindung ja gleich über den Konstruktor aufgebaut
ist eine schlechte Idee, denn ein Konstruktor sollte am besten keine Fehler verursachen können.

Spricht etwas dagegen, die Verbindung erst bei der ersten Abfrage aufzubauen und dann die Datenbankklasse überall (z.B. über eine header.inc.php) einzubinden?
das nennt sich LazyLoading und wird normal überall gemacht ;) Pear, Zend-Framework usw.

Ist es nicht generell sinnvoller, die Verbindung erst bei der ersten Abfrage einzubauen? Weil es kann ja auch Dateien geben, die nicht bei jedem Aufruf eine MySQL-Verbindung brauchen.
ja und nein.
Prinzipiel gut, mache ich auch so (andere Archtiektur deswegen fällt bei mir folgender Punkt weg), jedoch solltest du daran denken, dass es vllt ganz sinnvoll ist am Anfang auch gleich zu checken ob die Verbindung überhaupt korrekt aufgebaut wurde.

Du hast halt immer eine Abfrage "Hey, bin ich schon verbunden?" und das bei jeder Anfrage an die DB.
Das kann eine einfache If-Bedingung auf eine Variable sein, das kostet aber nu wirklich keine Leistung. Dagegen ist ne foreach-Schleife ne Todsünde ;)

Einfacher wäre zu sagen: Wenn ich keine DB brauche, binde ich halt die Klasse einfach nicht ein.
und wie machst du das mit einem front-controller? oder soll man in jeder datei die global.inc.php includen? :roll:
 
und wie machst du das mit einem front-controller? oder soll man in jeder datei die global.inc.php includen? :roll:


was spricht gegen ein require_once(''db.php); in jeder Datei, die Datenbankzugriffe benötigt? Damit ist sichergestellt, dass die Datei geladen wird, und der Fehler bei mehrfachdefinitin wird auch unterbunden.
 
Neija eine Programm ist deutlich strukturierter, wenn alles durch einen FrontController geht, als wenn es tausend Einstiegspunkte gibt, bei der jeder der Punkte noch verschiedene Dinge einbinden oder auch sein lassen kann.
 
Betrachten wir das Programm als ein C++ Programm, so wurde mir letztes Semester beigebracht, dass jede Klasse jeweils diejenigen Headerdateien einbindet, die sie gerade benötigt.
Nebenbei wird in den Headerdateien dafür gesorgt, dass Mehrfacheinbindungen nicht stattfinden können und somit keine Probelem auftauchen.
Beides ist exakt das, was ich hier vorschlagen, in diesem Falle halt auf PHP übertragen.
Warum soll mein Script / Programm etwas laden, was es vielleicht nie benötigt? Wenn ich eine Klasse oder eine Seite oder einen Affen habe, der der Überzeugung ist er müsse mit meiner Datenbank kommunizieren, so kann ich ihm dafür eine Schnittstelle bereitstellen. Anfordern soll er sie aber gefälligst selber.

Edit: Für ein Abbild eben jener strukturierung gibts es Hilfmittel, darunter allen voran die Klassendiagramme. Sind für PHP sicher nur je nach Programmierstil geeignet, aber wenn man sie ein wenig abwandelt bestimmt auch auf Homepages gut umsetzbar.
 
vielen Dank für euere Antworten.

Es scheint ja unterschiedliche Meinungen dazu zu geben.
Ich kann mir eigentlich nicht vorstellen, dass die if-Abfrage "mit Datenbank verbunden?", die in der Query-Funktion notwendig ist, so viel ausmacht.
Andererseits finde ich es aber schon auch verständlich, dass man nur das einbindet, was man braucht.
Hat noch jemand dazu eine Meinung, wie man sowas "normalerweise" macht?

Und:
Wenn ich mich dafür entscheiden sollte, die Klasse nur dort einzubinden, wo sie wirklich benötigt wird, sollte ich die Verbindung dann trotzdem über eine if-Abfrage in der Query-Anweisung aufbauen? Ansonsten wird ja in einer Datei, die nur ab und zu eine Datenbankverbindung benötigt wird (z.B. Formular, dass nur beim Abschicken eine DB-Verbindung benötigt) jedes Mal eine DB-Verbindung hergestellt. (Außer ich würde die Klasse irgendwo mitten im Code, der nur bei Datenbankbenutzung ausgeführt wird, includen, aber das ist ja dann doch etwas unübersichtlich.)

@ice-breaker:
mit "Datenbankverbindung über den Konstruktor aufbauen" meinte ich nicht, den kompletten Quellcode in den Konstruktor zu schreiben, sondern:
PHP:
function __construct() 
{
$this->connect();
}
So etwas ist doch in Ordnung, oder? (ist die erste Klasse, die ich schreibe, habe sonst immer alles prozedural gemacht)

Eine Prüfung, ob die Verbindung korrekt aufgebaut wurde, habe ich:
PHP:
    private function connect()
    {
        if (!$this->connection) {
            $this->connection = @mysql_connect($this->db_host, $this->db_user, $this->db_password);
            if (empty($this->connection)) {
                $this->error('Beim Verbinden');
            }
            $db_select = @mysql_select_db($this->db_name, $this->connection);
            if (empty($db_select)) {
                $this->error('Beim Auswählen der Datenbank');
            }
            return $this->connection;
        }
    }
 
Es zählen dazu auch alle Operationen die der Konstruktr ausführt ;)

Man sagt eben wenn ich in einer Zeile einen Konstrukor aufrufe sollte das ein "safe call" sein, also sollte diese Aufruf gar keinen Fehelrursachen können.
Eine Möglichkeit das zu umgehen wären statische factory-Methoden, diese dürfen Probleme gleich melden.
 
Wo hier gerade das Thema dabei ist: Macht es dir was aus zu erklären, warum der Konstruktor keinen Fehler hevorrufen sollte?
 
Warum habe ich nur das Gefühl, dass da jemand "gegen mich arbeitet"? :roll:

Aus einfachen Gründen. Einerseits welchen Sinn hat ein Konstruktor? Er soll ein Objekt anlegen, und dieses wird gleich in einer Referenz gespeichert, was passiert aber nun wenn im Konstruktor was schief läuft? Ein Objekt wird nie korrekt initialisiert, man kann es komplett vergessen, in die Tonne kloppen. Auch wenn Exceptions geworfen werden, wird der Punkt der Speicherung des Objektes in eine Variable komplett übersprungen, was das für den Rest der Laufzeit eines Scriptes bedeuten kann, will ich gar net sagen.
Es gehört auch einfach nicht zum guten Stil, schau dir doch auch mal professionelle Klassen, die mach es ja auch net ohne Grund ;)
 
ok, vielen Dank.
Das (also, wenn ich die DB-Verbindung nicht im Konstruktor öffne) heißt ja dann, dass egal, ob ich die Klasse überall einbinde oder nicht, vor jeder Datenbankabfrage geprüft werden muss, ob eine DB-Verbindung besteht, oder? Eine andere Möglichkeit wäre natürlich, dass ich immer vor der ersten DB-Abfrage in der jeweiligen Datei noch "$db->connect()" hinschreibe, aber da ist die automatische Version mit der if-Abfrage ja bequemer.
 
Warum habe ich nur das Gefühl, dass da jemand "gegen mich arbeitet"? :roll:

Ich arbeite nicht gegen dich, das hat mich jetzt echt interessiert. Denn meine Logik wäre jetzt gewesen, was nutzt mir eine Datenbankklasse, die nicht funktioniert.. dann aknn die lieber nen E_USER_ERROR triggern, und das dann beenden. Oder einfach nur ne Warnung, und dann kann man per ->isConnected() überprüfen, ob die Verbindung hergestellt wurde..