IT-Academy Logo
Sign Up Login Help
Home - Programmieren - PHP - PHP: eine einfache mySQL Klasse



PHP: eine einfache mySQL Klasse

PHP und mySQL: eine oft sehr erfolgreich verwendete Kombination. Gerade bei kleineren Web-Projekten erspart man sich oft Arbeit, indem man die Datenbank nicht 'schön' einbindet. Die Klasse, die in diesem Artikel erstellt wird, soll den Umgang mit Datenbanken sehr vereinfachen und zusätzlich auch immer ohne große Änderungen verwendbar sein.


Autor: Goe rgi (Goergi)
Datum: 02-05-2006, 19:44:29
Referenzen: keine
Schwierigkeit: Fortgeschrittene
Ansichten: 29587x
Rating: Bisher keine Bewertung.

Hinweis:

Für den hier dargestellte Inhalt ist nicht der Betreiber der Plattform, sondern der jeweilige Autor verantwortlich.
Falls Sie Missbrauch vermuten, bitten wir Sie, uns unter missbrauch@it-academy.cc zu kontaktieren.

[Druckansicht] [Als E-Mail senden] [Kommentar verfassen]



Dieser Artikel soll nur wenig über Klassen beinhalten, wer also ein „class Auto { }“-Beispiel sucht, der möge sich unter „Objektorientiertes Programmieren mit PHP“ schlau machen!
Um die Funktionsweise der Klasse zu verstehen, sollte man Kenntnisse in PHP haben!

Was soll/wird unsere Klasse nun später alles können? Man sollte die Zugänge zu verschiedenen mySQL-Servern leicht managen können; Verbindungen sollen hergestellt und getrennt werden; Befehle sollen ausgeführt werden und natürlich auch Datensätze wieder ausgelesen; dann sollen auch noch die Zugriffe auf die Datenbank gezählt werden und zu letzt noch eine Fehlerausgabe.

Im folgenden Abschnitt des Artikels kommen nun zuerst die Code-Schnipsel und dann die Erklärung. Zum Ende einmal die gesamte Datei und dann ein kleines Anwendungsbeispiel. Wichtig: die Kommentare in den Code-Schnipseln erklären auch Einiges!

Als erstes brauchen wir natürlich eine Datei; ich nenne sie class.mySQL.php

class.mySQL.php
<?php

##################
# Hier kommt die Verwaltung der Zugangsdaten
##################

class mySQL {
var
$connected = FALSE; // besteht eine Verbindung?
var $host; // unser mySQL Server
var $user; // der mySQL-Benutzer
var $pswd; // das zugehörige Passwort
var $dbname; // der Name der Datenbank
var $verbindung; // die Kennung der Verbindung
var $sql_query; // die zuletzt gestellte Anfrage
var $query_counter; // wie viele Anfragen wurden schon gemacht?

function mySQL($ID = DB_STANDARD) {} // Konstruktor, erstellt die Verbindung
function DBQueries() {} // liefert die Anzahl der Anfragen
function DrawDBQueries() {} // liefert die Anzahl der Anfragen als Text
function query($sql) {} // sendet einen Befehl an die Datenbank
function select($sql, $anzahl = NULL) {} // holt Datensätze aus der Datenbank
function error($error_type) {} // gibt die Fehlermeldungen aus

// wenn das Skript nicht mit PHP5 ausgeführt wird, folgende Funktion einfach löschen!
function __destruct() {} // beendet die Verindung

}
?>

Diese Datei beinhaltet jetzt schon die Grundvorstellungen.
Kleine Anmerkung am Rande: seit PHP 5 gibt es auch Destruktoren bei Klassen!
Der Funktionsname „__destruct“ (zwei Unterstriche) wird automatisch beim Zerstören einer Klasse ausgeführt. Beim Zerstören unserer Klasse wird einfach die Verbindung wieder getrennt (wenn eine solche besteht). Dies ist zwar nicht nötig, da am Ende eines Skripts automatisch die Verbindungen getrennt werden, aber es schadet ja nicht und kann bei der Verwendung von vielen Servern auch Speicher sparen.
Wenn eine ältere Version verwendet wird, dann ist diese Funktion einfach zu löschen.

zu Beginn gleich die Account-Verwaltung
<?php
##### Hier folgen die Einstellungen der Verbindungen

define("DB_STANDARD", 1);
define("DB_TEST", 2);

# Verbindung 'STANDARD'
$mySQL_settings[1]['host'] = 'localhost';
$mySQL_settings[1]['user'] = 'root';
$mySQL_settings[1]['pswd'] = '';
$mySQL_settings[1]['dbname'] = 'standard';

# Verbindung 'TEST'
$mySQL_settings[2]['host'] = '127.0.0.1:3306';
$mySQL_settings[2]['user'] = 'username';
$mySQL_settings[2]['pswd'] = 'password';
$mySQL_settings[2]['dbname'] = 'database';

####################
?>

Für jede Verbindung muss eine fortlaufende Nummer definiert werden (mit define). Der Name ist bis auf wenige Wörter beliebig und sollte aussagekräftig sein. Ein „DB_“ als Präfix ist also nichts Schlechtes.
Die Variable $mySQL_settings ist ein mehrdimensionales Array, in dem die Daten gespeichert werden. Die „erste Dimension“ enthält die fortlaufende Nummer der Verbindung und die „zweite Dimension“ die eigentlichen Daten.

und nun die erste Funktion: der Konstruktor
<?php
function mySQL($ID = DB_STANDARD) {
global
$mySQL_settings;
$this->host = $mySQL_settings[$ID]['host'];
$this->user = $mySQL_settings[$ID]['user'];
$this->pswd = $mySQL_settings[$ID]['pswd'];
$this->dbname = $mySQL_settings[$ID]['dbname'];
$this->verbindung = @mysql_connect($this->host, $this->user, $this->pswd);
if (
$this->verbindung === FALSE) {
$this->error("CONN.OPEN");
}
if (@
mysql_select_db($this->dbname, $this->verbindung) === FALSE) {
$this->error("DB.SELECT");
} else {
$this->connected = TRUE;
}
}
?>

Beim Erstellen einer neuen Instanz dieser Klasse wird automatisch der Konstruktor ausgeführt. Dieser schreibt auch gleich die Zugangsdaten in die entsprechenden Variablen. Danach wird sofort versucht eine Verbindung aufzubauen. Das „@“ vor den Funktionsnamen fängt die Fehlermeldungen ab. Wenn die Verbindung erfolgreich gestartet wurde, wird die Datenbank ausgewählt, im Falle, dass auch dies gut geht, wird die Variable connected auf TRUE gesetzt – wir sind also zu einer Datenbank verbunden. Sollte eine dieser Aktionen fehlschlagen, wird die error()-Funktion aufgerufen.

Der Destruktor (nur bei PHP 5)
<?php
// wenn das Skript nicht mit PHP5 ausgeführt wird, folgende Funktion einfach löschen!
function __destruct() {
if (!
$this->connected) {
$this->error("NO CONN");
} else {
if (@
mysql_close($this->verbindung) === FALSE) {
$this->error("CONN.CLOSE");
}
}
}
?>

Wenn eine Verbindung besteht, wird diese beim Zerstören der Klasse beendet (was soll auch beendet werden, wenn keine Verbindung besteht?)

Unsere Zählerausgabe
<?php
function DBQueries() {
if (!
$this->connected) {
$this->error("NO CONN");
} else {
return
$this->query_counter;
}
}

function
DrawDBQueries() {
if (!
$this->connected) {
$this->error("NO CONN");
} else {
if (
$this->DBQueries == 1) {
$text = "Es war 1 mySQL-Abfrage nötig";
} else {
$text = "Es waren ".$this->DBQueries." mySQL Abfragen nötig";
}
}
return
$text;
}
?>

Diese zwei Funktionen kümmern sich nur darum, die Anzahl der mitgezählten Datenbankanfragen wieder auszugeben. Die erste liefert nur die Zahl, die zweite Funktion liefert einen String, der grammatikalisch korrekt ist ;-)

Die Befehl-Senden-Funktion
<?php
function query($sql) {
if (!
$this->connected) {
$this->error("NO CONN");
} else {
$this->sql_query = $sql;
$this->query_counter++;
$result = @mysql_query($this->sql_query, $this->verbindung);
if (
$result === FALSE) {
$this->error("QUERY FAILED");
} else {
return
$result;
}
}
}
?>

Wenn eine Verbindung beseht, wird der SQL-Befehl an die Datenbank geschickt. Hier kommt auch der zuvor angesprochene Zähler zum Einsatz: jener wird um eins erhöht. Wenn mySQL keinen Fehler meldet, wird dieser Rückgabewert auch von unserer Funktion zurückgegeben.

Die Abfrage-Funktion
<?php
function select($sql, $anzahl = NULL) {
if (!
$this->connected) {
$this->error("NO CONN");
} else {
$result = $this->query($sql);
if (
$result !== FALSE) {
$anzahl1 = @mysql_num_rows($result);
$anzahl = $anzahl1;
for(
$i = 0; $i < $anzahl; $i++) {
$array[$i] = @mysql_fetch_object($result);
}
}
}
return
$array;
}
?>

Diese Funktion ist nun etwas komplizierter aufgebaut (sie wird natürlich auch nur dann ausgeführt wenn eine Verbindung besteht). Zuerst wird die gestellte Anfrage an unsere Funktion query() übergeben. Wenn diese nicht fehlschlägt, wird jeder gelieferte Datensatz in einer Schleife in ein Array gespeichert, welches dann auch zurückgegeben wird. Wenn zusätzlich noch eine Variable für die Anzahl übergeben wird, dann wird die Anzahl der gefundenen Datensätze dort hinein gespeichert.

Es gibt deshalb diese zwei Funktionen, da bei der ersteren kein verwertbarer Rückgabewert erwartet wird; von der zweiten wollen wir aber die Daten geliefert bekommen.

Ausgabe der Fehlermeldungen
<?php
function error($error_type) {
switch (
$error_type) {
case
'CONN.OPEN':
$text = "Beim Öffnen der Verbindung ist ein Fehler aufgetreten";
break;

case
'CONN.CLOSE':
$text = "Beim Schließen der Verbindung ist ein Fehler aufgetreten";
break;

case
'NO CONN':
$text = "Die angeforderte Aktion konnte nicht durchgeführt werden, da keine Verbindung zur Datenbank besteht!";
break;

case
'DB.SELECT':
$text = "Beim Auswählen der Datenbank ist ein Fehle aufgetreten. Ev. ist die Datenbank nicht vorhanden";
break;

case
'QUERY FAILED':
$text = "Während folgender Abfrage ist ein Fehler aufgetreten:\n\n".$this->sql_query;
break;

default:
$text = "Es ist folgender, unbekannter Fehler aufgetreten: ".$error_type;
}
if (
$this->connected) {
$text .= "\n\nmySQL meldet:\nFehler-Nummer: ".@mysql_errno($this->verbindung)."\nFehler-Beschreibung: ".@mysql_error($this->verbindung);
}
echo
$text."\n";
}
?>

Die letzte Funktion ist unsere Fehler-Funktion. Sie wird von allen anderen Funktionen aufgerufen, wenn eine mySQL-Aktion fehlschlug. Hier wird einfach zu den Fehlern ein Text ausgegeben und (wenn Verbindung vorhanden) die Fehlererklärung von mySQL.

Anmerkungen: die Klasse ist natürlich beliebig erweiterbar und soll nur die gängigsten Funktionen beinhalten. Als Beispiel: erweiterbar wäre eine Funktion, die eine Datenbank neu anlegt. Da dies im Normalfall nur einmal geschieht, habe ich auf solches verzichtet.
Anfragen, die zigtausende große Ergebnisse zurückliefern, sollten nicht mit select() abgefragt werden! Dies ist zwar möglich, kostet aber enorm viel Speicher.
Die Fehlermeldungen können auch ganz einfach gelöscht bzw. geändert werden, wenn diese störend sind.

Hier noch ein kleines Anwendungsbeispiel für die Funktionen:
<?php

#### Testdatei zur Demonstration der mySQL-Klasse

include("class.mySQL.php");

$db = new mySQL(); // wenn kein Argument angegeben wird, dann wird die erste Verbindung benutzt
$db->query("INSERT INTO table VALUES('1', 'test')"); // ein Befehlt, von dem kein verwertbarer Rückbabewert kommt

$sql = new mySQL(DB_TEST); // neue Verbindung zu DB_TEST
$daten = $sql->select("SELECT * FROM table"); // einfache Abfrage

for ($i = 0; $i < count($row); $i++) {
echo
"Spalte1: ".$daten[$i]->column1; // hier werden in einer Schleife die Daten ausgegeben
}

$daten = $sql->select("SELECT * FROM table WHERE test LIKE 'testtext'", &$anzahl); // erweiterte Anfrage mit Anzahl
if ($anzahl == 0) {
echo
"Es wurde kein passender Datensatz gefunden"; // wenn die Anzahl Null ist, eine Meldung ausgeben
}

echo
$sql->DrawDBQueries(); // den formatierten String ausgeben (Anzahl der Abfragen auf die $sql-Verbindung)

$gesamt = $db->DBQueries()+$sql->DBQueries(); // die Anfragen beider Datenbanken zusammenzählen
echo "Es wurden insgesamt ".$gesamt." Anfragen getätigt"; // und diese dann ausgeben

unset($db); unset($sql); // beide Verbindungen trennen und Speicher freigeben

?>

Um die Klasse benutzen zu können, wird sie erst „included“. Da wird beim ersten Erstellen einer Klasse kein Argument übergeben haben, wird die Standard-Verbindung gewählt. Mit query() führen wir nun ein einfaches „INSERT“ durch – dieses liefert ja keine Daten zurück ? deshalb query() und nicht select().
In $sql wird nun eine neue Verbindung zur DB_TEST hergestellt. Danach wird in $daten das komplette Ergebnis gepeichert. Nun wird die Schleife so lange ausgeführt, bis alle Elemente des Arrays $daten abgearbeitet wurden. Der nächsten Anfrage wird zusätzlich das Argument &$anzahl übergeben. Das & ist wichtig! Die Funktion schreibt uns die Anzahl der gefundenen Datensätze in diese Variable, die wir im weiteren Skript mit $anzahl ansprechen können. Dies tun wir auch gleich und überprüfen, ob überhaupt ein Datensatz geliefert wurde. Wenn nicht, kommt die entsprechende Meldung. Wenn wir nun wissen wollen, wie viele Abfragen über die $sql-Verbindung gegangen sind, geschieht dies mit DrawDBQueries(). Um die Anzahl der Abfragen zu erfahren, die insgesamt (auch über die erste Verbindung) getätigt wurden, summieren wir die einzelnen Werte und können auch diese Anzahl ausgeben. Nun werden noch die zwei erstellten Klassen zerstört und die Verbindungen damit getrennt.
Wenn man sich erst an die neue Schleifenform gewöhnt hat, lässt es sich mit einer solchen Klasse viel schneller arbeiten.




Und zum Schluss nun die komplette Klasse:
<?php

##### Hier folgen die Einstellungen der Verbindungen

define("DB_STANDARD", 1);
define("DB_TEST", 2);

# Verbindung 'STANDARD'
$mySQL_settings[1]['host'] = 'localhost';
$mySQL_settings[1]['user'] = 'root';
$mySQL_settings[1]['pswd'] = '';
$mySQL_settings[1]['dbname'] = 'standard';

# Verbindung 'TEST'
$mySQL_settings[2]['host'] = '127.0.0.1:3306';
$mySQL_settings[2]['user'] = 'username';
$mySQL_settings[2]['pswd'] = 'password';
$mySQL_settings[2]['dbname'] = 'database';

####################

class mySQL {
var
$connected = FALSE;
var
$host;
var
$user;
var
$pswd;
var
$dbname;
var
$verbindung;
var
$sql_query;
var
$query_counter;

function
mySQL($ID = DB_STANDARD) {
global
$mySQL_settings;
$this->host = $mySQL_settings[$ID]['host'];
$this->user = $mySQL_settings[$ID]['user'];
$this->pswd = $mySQL_settings[$ID]['pswd'];
$this->dbname = $mySQL_settings[$ID]['dbname'];
$this->verbindung = @mysql_connect($this->host, $this->user, $this->pswd);
if (
$this->verbindung === FALSE) {
$this->error("CONN.OPEN");
}
if (@
mysql_select_db($this->dbname, $this->verbindung) === FALSE) {
$this->error("DB.SELECT");
} else {
$this->connected = TRUE;
}
}

// wenn das Skript nicht mit PHP5 ausgeführt wird, folgende Funktion einfach löschen!
function __destruct() {
if (!
$this->connected) {
$this->error("NO CONN");
} else {
if (@
mysql_close($this->verbindung) === FALSE) {
$this->error("CONN.CLOSE");
}
}
}

function
DBQueries() {
if (!
$this->connected) {
$this->error("NO CONN");
} else {
return
$this->query_counter;
}
}

function
DrawDBQueries() {
if (!
$this->connected) {
$this->error("NO CONN");
} else {
if (
$this->DBQueries == 1) {
$text = "Es war 1 mySQL-Abfrage nötig";
} else {
$text = "Es waren ".$this->DBQueries." mySQL Abfragen nötig";
}
}
return
$text;
}

function
query($sql) {
if (!
$this->connected) {
$this->error("NO CONN");
} else {
$this->sql_query = $sql;
$this->query_counter++;
$result = @mysql_query($this->sql_query, $this->verbindung);
if (
$result === FALSE) {
$this->error("QUERY FAILED");
} else {
return
$result;
}
}
}

function
select($sql, $anzahl = NULL) {
if (!
$this->connected) {
$this->error("NO CONN");
} else {
$result = $this->query($sql);
if (
$result !== FALSE) {
$anzahl1 = @mysql_num_rows($result);
$anzahl = $anzahl1;
for(
$i = 0; $i < $anzahl; $i++) {
$array[$i] = @mysql_fetch_object($result);
}
}
}
return
$array;
}

function
error($error_type) {
switch (
$error_type) {
case
'CONN.OPEN':
$text = "Beim Öffnen der Verbindung ist ein Fehler aufgetreten";
break;

case
'CONN.CLOSE':
$text = "Beim Schließen der Verbindung ist ein Fehler aufgetreten";
break;

case
'NO CONN':
$text = "Die angeforderte Aktion konnte nicht durchgeführt werden, da keine Verbindung zur Datenbank besteht!";
break;

case
'DB.SELECT':
$text = "Beim Auswählen der Datenbank ist ein Fehle aufgetreten. Ev. ist die Datenbank nicht vorhanden";
break;

case
'QUERY FAILED':
$text = "Während folgender Abfrage ist ein Fehler aufgetreten:\n\n".$this->sql_query;
break;

default:
$text = "Es ist folgender, unbekannter Fehler aufgetreten: ".$error_type;
}
if (
$this->connected) {
$text .= "\n\nmySQL meldet:\nFehler-Nummer: ".@mysql_errno($this->verbindung)."\nFehler-Beschreibung: ".@mysql_error($this->verbindung);
}
echo
$text."\n";
}

}
?>


Viel Spaß damit!


Paike
Rookie
Beitrag vom:
22-04-2008, 11:28:42

Fehler

Hi,
der Teil zur Ausgabe der Daten enthält einen Fehelr, es sollte heißen:

for ($i = 0; $i < count($daten); $i++) {
echo "Spalte1: ".$daten[$i]->column1; // hier werden in einer Schleife die Daten ausgegeben
}

Gruß,
Paike

-----------------------------------------------------


[back to top]



Userdaten
User nicht eingeloggt

Gesamtranking
Werbung
Datenbankstand
Autoren:04510
Artikel:00815
Glossar:04116
News:13565
Userbeiträge:16552
Queueeinträge:06247
News Umfrage
Ihre Anforderungen an ein Online-Zeiterfassungs-Produkt?
Mobile Nutzung möglich (Ipone, Android)
Externe API Schnittstelle/Plugins dritter
Zeiterfassung meiner Mitarbeiter
Exportieren in CSV/XLS
Siehe Kommentar



[Results] | [Archiv] Votes: 1158
Comments: 0