# MySQL und PHP

Ask any DBA to give you a short list of the best databases that are available, and it's guaranteed that MySQL will make the cut.
Autor unbekannt

Da Sie nun wissen, wie eine MySQL-Datenbank mit Perl angesprochen wird, werde ich Ihnen erklären, wie Sie dies mit PHP realisieren können.

# Datenbankverbindung herstellen

PHP bietet für den Zugriff auf eine MySQL-Datenbank eine API an, die bereits von vornherein in PHP-Scripts zur Verfügung steht. Diese API kapselt alle erforderlichen Funktionen, um mit MySQL kommunizieren und arbeiten zu können. Darunter fällt natürlich auch eine Funktion, um die Verbindung herzustellen: mysql_connect. Sie benötigt dafür jedoch drei Parameter: den Host und ggf. den Port, über den die Datenbank erreichbar ist, einen Benutzernamen und ein Passwort. Der Port ist normalerweise 3306, außer natürlich, Sie haben dies in der my.ini geändert.

resource mysql_connect(string host, string uid, string pwd)

Konnte die Verbindung zur Datenbank erfolgreich hergestellt werden, gibt die Funktion eine Resource bzw. ein Handle zurück, mit der bzw. dem im Script später die Identifikation dieser Verbindung vorgenommen wird. Konnte die Verbindung jedoch nicht aufgebaut werden, z. B. aufgrund eines falschen Hosts oder einer falschen Benutzerkennung, gibt die Funktion FALSE zurück.

Wurde die Datenbank lokal auf dem Rechner installiert, können Sie als host entweder localhost oder 127.0.0.1 angeben. Ist die Datenbank auf einem anderen Rechner installiert, sollten Sie nach Möglichkeit die IP-Adresse angeben. Den Port müssen Sie nur dann angeben, falls er sich vom Standardport 3306 unterscheidet. Er wird dann mit einem Doppelpunkt hinter dem Hostnamen notiert.

Die Benutzerdaten sind abhängig davon, welche Festlegungen Sie bei der MySQL-Installation getroffen haben. Den Benutzernamen geben Sie als Parameter uid (Abkürzung für »user identification«) und das Passwort als Parameter pwd (Abkürzung für »passwor) an. Da alle diese Parameter als Strings übergeben werden, dürfen Sie natürlich die Anführungsstriche nicht vergessen!

Je nach Konfiguration von PHP wird ein fehlerhafter Verbindungsaufbau oft automatisch mit einer Fehlermeldung von PHP quittiert. Um dies zu verhindern und eine eigene Fehlermeldung auszugeben, können Sie vor der Funktion ein @ notieren. Dieser Operator unterbindet alle Fehlermeldungen, Dies gilt im Übrigen auch für alle anderen PHP-Funktionen.die eine Funktion auslösen könnte.

$connection = mysql_connect('localhost','user','password');  
if($connection)  
{  
  echo '<p>Es klappt! Die Verbindung zur Datenbank wurde   
        hergestellt!</p>';  
}  
else  
{  
  echo '<p>Die Verbindung zur Datenbank konnte leider  
           nicht hergestellt werden. Bitte versuchen   
           Sie es zu einem späteren Zeitpunkt noch   
           einmal.</p>';  
}

Eine Datenbankverbindung bindet jedoch immer Leistungsreserven des Servers, auf dem das Script ausgeführt wird. Auch wenn heutige Server oft über sehr große Reserven verfügen, beschleunigt es den Ablauf eines Scripts, wenn Sie Verbindungen beenden, sobald sie für den weiteren Ablauf des Scripts nicht mehr benötigt werden. Genau das Gegenteil wird aber bewirkt, wenn Sie während eines Scripts mehrmals eine Verbindung herstellen und wieder beenden! Zum Beenden einer Verbindung können Sie die Funktion mysql_close verwenden.

bool mysql_close([resource connection])

Die Angabe einer Verbindungskennung ist optional. Wenn Sie jedoch keine angeben, werden alle aktiven Verbindungen beendet. Bei Erfolg gibt die Funktion TRUE zurück, andernfalls FALSE.

# Datenbank auswählen

Sobald Sie eine Verbindung zu einer MySQL-Datenbank aufgebaut haben, können Sie eigentlich schon fast loslegen. Wie auch in der Konsole von MySQL müssen Sie zuvor allerdings noch eine Datenbank auswählen, mit der Sie arbeiten möchten. Auch dafür stellt die MySQL-API eine Funktion bereit: mysql_select_db.

bool mysql_select_db(string database [, resource connection])

Diese Funktion erwartet als Parameter auf jeden Fall den Namen der Datenbank, die Sie für die folgenden SQL-Anweisungen verwenden möchten. Damit Sie bei mehreren Verbindungen gleichzeitig auch für die richtige Verbindung die gewünschte Datenbank auswählen, können Sie als zweiten Parameter optional das Datenbankhandle angeben. Wurde die Datenbank erfolgreich ausgewählt, gibt die Funktion TRUE zurück. Trat bei der Auswahl ein Fehler auf, lautet der Rückgabewert FALSE.

$connection = mysql_connect('localhost','user','password');  
if($connection)  
{  
  if(mysql_select_db('bspbuecher'))  
  {  
    echo '<p>Datenbank wurde ausgewählt!</p>';  
  }  
  else  
  {  
    echo '<p>Datenbank konnte nicht ausgewählt werden!</p>';  
  }  
}  
else  
{  
  echo '<p>Verbindung konnte nicht hergestellt werden!</p>';  
}

Da der Rückgabewert der Funktion mysql_select_db nicht für den weiteren Verlauf des Scripts wichtig ist, kann die Funktion bequem als Bedingung einer if-Abfrage aufgerufen werden.

# Konfigurationsdatei

Wenn Sie viele verschiedene PHP-Scripts haben, in denen eine Verbindung zu MySQL hergestellt werden soll, und sich die Parameter für Host, Benutzernamen, Passwort und Datenbank nicht unterscheiden, ist es sinnvoll, diese Daten in eine externe Datei auszulagern, die dann im entsprechenden Script lediglich eingebunden werden muss. Das Einbinden der Datei erfolgt dann über die include-Anweisung. Aus diesem Grund hat sich für solche Dateien auch eine spezielle »doppelte« Endung eingebürgert. Damit man eine solche Konfigurationsdatei schneller von anderen Dateien unterscheiden kann, wird sie mit der Endung .inc.php abgespeichert. Dies hat auch einen sicherheitstechnischen Aspekt. Denn Dateien, die auf .php enden, werden vor dem Übertragen zum Benutzer immer erst an den PHP-Interpreter übergeben. Somit wird es für einen Außenstehenden fast unmöglich, die heiklen Daten im Klartext lesen zu können. Das folgende Beispiel stellt eine solche Konfigurationsdatei dar, die unter dem Dateinamen mysql.inc.php abgespeichert wird.

<?php

  $sql['host'] = 'localhost';
  $sql['uid'] = 'user';
  $sql['pwd'] = 'password';
  $sql['db'] = 'bspbuecher';

?>

Listing 5.1: Beispiel für eine Konfigurationsdatei

In Listing 5.1 wird ein assoziatives Array definiert, das vier Elemente mit den wichtigsten Informationen enthält, um eine Datenbankverbindung aufzubauen und die richtige Datenbank auszuwählen. Der Vorteil ist, dass Sie die Daten nur in einer Datei ändern müssen, falls sich einmal das Passwort oder der Name der Datenbank ändert. Eine erhebliche Erleichterung!

In einem Script, das die Verbindung aufbauen soll, könnte dies dann folgendermaßen aussehen:

// ---[SNIP]---  
include('mysql.inc.php');  
$connection = mysql_connect($sql['host'],$sql['uid'],$sql['pwd']);  
if($connection)  
{  
  if(mysql_select_db($sql['db']))  
  {  
// ---[SNAP]---

Wo Sie die Datei ablegen, ist eigentlich egal. Wenn Sie Ihre Seite auf einem Server ablegen, bei dem Sie auch Zugriff auf das Elternverzeichnis des Document-Root-Verzeichnisses haben, sollten Sie die Datei am besten dort ablegen. Ein Benutzer Ihrer Webseite kann auf dieses Verzeichnis auf jeden Fall nicht zugreifen, und so ist die Datei noch einmal zusätzlich vor ihm geschützt.

# Anfragen stellen

Um nun eine SQL-Anweisung an eine MySQL-Datenbank zu übergeben, benötigen Sie die Funktion mysql_query. Die Anweisung bezieht sich dann auf die Datenbank, die zuvor mit mysql_select_db ausgewählt wurde.

Ein wichtiger Hinweis: Während Sie in der MySQL-Konsole alle Anweisungen mit einem Semikolon ; abschließen mussten, dürfen Sie dies bei PHP nicht. Das Semikolon in der Konsole zeigt MySQL das Ende einer SQL-Anweisung an und ermöglicht es, mehrere unterschiedliche Anweisungen hintereinander zu übergeben. In PHP müssen Sie jedoch alle Anweisungen einzeln übergeben. Den Grund dafür werden Sie im Laufe dieses und der nächsten Abschnitt noch genauer kennen lernen.

Mit mysql_query können Sie eine beliebige SQL-Anweisung ausführen. Dabei ist es egal, ob es eine SELECT-, INSERT-, UPDATE- oder DELETE-Anweisung ist. Aber auch alle anderen Anweisungen, wie CREATE TABLE oder DROP DATABASE, sind erlaubt.

Die Syntax von mysql_query:

resource mysql_query(string query [,resource connection])

Als Parameter query müssen Sie die auszuführende SQL-Anweisung als String übergeben. Optional können Sie auch noch das Datenbankhandle übergeben, was aber nur bei mehreren aktiven Verbindungen notwendig ist. Je nachdem, ob die Anfrage erfolgreich war oder nicht und welche Art von SQL-Anweisung an die Funktion übergeben wurde, gibt diese entweder eine Ressource, TRUE oder FALSE zurück.

  • Resource
    Eine Ressource wird immer dann zurückgegeben, wenn eine SELECT- oder SHOW-Anweisung an die Funktion, respektive die Datenbank, übergeben wurde.
  • TRUE
    Wurde eine andere Anweisung übergeben und wurde diese erfolgreich ausgeführt, gibt die Funktion TRUE zurück.
  • FALSE
    Trat während der Ausführung der Anweisung ein Fehler auf, wird FALSE zurückgegeben.

Der Grund für diese drei verschiedenen Rückgabewerte ist, dass nicht jede SQL-Anweisung ein Ergebnis liefert. Während Sie mit SELECT oder SHOW Daten von MySQL anfordern, werden bei DELETE oder INSERT Daten an MySQL übergeben. Dementsprechend müssen Sie auf den Rückgabewert der Funktion mysql_query auch unterschiedlich reagieren.

// ---[SNIP]---  
$result = mysql_query('SELECT * FROM bspverlage');  
if($result)  
{ ...  
// ---[SNAP]---

In $result wird bei erfolgreich ausgeführter Anweisung eine Ressource gespeichert. Um das Ergebnis bearbeiten zu können, müssen Sie dann z. B. mysql_fetch_row oder mysql_fetch_array ausführen. Durch die Überprüfung von $result in einer if-Abfrage können Sie ermitteln, ob die SQL-Anweisung erfolgreich war oder nicht.

// ---[SNIP]---  
$result = mysql_query('DELETE FROM bspverlage');  
if($result)  
{ ...  
// ---[SNAP]---

Wurde die Anweisung erfolgreich ausgeführt, enthält $result nun den Wert TRUE. Die Funktion mysql_affected_rows liefert dann die Anzahl der betroffenen Datensätze der SQL-Anweisung.

Sobald Sie Ergebnisse einer SQL-Anweisung nicht mehr benötigen, sollten Sie mit mysql_free_result den durch das Ergebnis belegten Speicher wieder freigeben. Dies ist nicht zwingend erforderlich, da der Speicher nach Ablauf eines PHP-Scripts automatisch wieder zur Verfügung steht. Auf Systemen mit wenig Arbeitsspeicher ist das manuelle Freigeben jedoch empfehlenswert.

bool mysql_free_result(resource result)

# Ergebnisverarbeitung bei SELECT oder SHOW

Die Funktion mysql_query gibt keine Ergebnisse aus Datenbankabfragen zurück, sondern im Fall einer SELECT- oder SHOW-Anweisung lediglich eine Ressource auf eine Tabelle, die das Abfrageergebnis enthält. Die Ergebnisse der Abfrage werden von MySQL zwischengespeichert und bei Bedarf zurückgegeben. Um nun an die Ergebnisse heranzukommen, benötigen Sie die Ressource, die mysql_query zurückgegeben hat.

Die wichtigste Funktion ist dabei mysql_num_rows, denn diese Funktion gibt die Anzahl der Zeilen der Ergebnistabelle zurück. Diese Zeilen entsprechen dann den Datensätzen, die auf die Anfrage passen. Wenn das Ergebnis der Abfrage keine Datensätze enthält, sind in der Ergebnistabelle dementsprechend 0 Datensätze gespeichert. Nur wenn ein Fehler aufgetreten ist, gibt die Funktion den Wert FALSE zurück.

integer mysql_num_rows(resource result)

In gleicher Weise können Sie auch die Anzahl der Spalten der Ergebnistabelle mit der Funktion mysql_num_fields ermitteln. Diese Funktion liefert jedoch entweder FALSE oder ein Ergebnis, das größer als 0 ist. Der Grund ist denkbar einfach, denn egal, ob die Ergebnistabelle einen Datensatz enthält oder nicht, sind auf jeden Fall so viele Spalten in der Ergebnistabelle definiert, wie in der SELECT-Anweisung angefordert wurden.

integer mysql_num_fields(resource result)

In Verbindung mit der Funktion mysql_result können Sie die Daten dann spalten- und zeilenweise ausgeben.

mixed mysql_result(resource result, integer row [, integer col])

Als ersten Parameter müssen Sie die Ressource der Ergebnistabelle angeben, gefolgt von der Zeile (bzw. dem Datensatz). Alternativ können Sie dann auch noch die Spalte aufführen. Die Zählung beginnt dabei, wie auch bei Arrays, mit 0.

$result = mysql_query('SELECT * FROM bspbuecher');  
if($result)  
{  
  echo '<table border="1">';  
  for($row = 0; $row < mysql_num_rows($result); $row++)  
  {  
    echo '<tr>';  
    for($col = 0; $col < mysql_num_fields($result); $col++)  
    {  
      $cell = mysql_result($result,$row,$col);  
      echo "<td>$cell</td>";  
    }  
    echo '</tr>';  
  }  
  echo '</table>';  
}

Dies ist zwar die einfachste Variante, um die Ergebnistabelle auszulesen, aber auch die denkbar langsamste. Da die Zellen einzeln ausgelesen werden, muss jedes Mal auf die Ergebnistabelle zugegriffen und die entsprechende Zelle gesucht werden. Bei einer Tabelle mit drei Zeilen und vier Spalten mag dies nicht weiter auffallen. Bei zehn Spalten und 10.000 Zeilen fällt dies jedoch deutlicher ins Gewicht.

Wesentlich schneller ist es, die Ergebnistabelle zeilenweise einzulesen, und zwar von Anfang bis Ende. Die Funktionen mysql_fetch_row, mysql_fetch_array und mysql_fetch_object lesen die Ergebnistabelle zeilenweise ein und liefern beim jeweils nächsten Aufruf auch den nächsten Datensatz, und zwar so lange, bis alle Datensätze ausgelesen wurden. Sie unterscheiden sich lediglich darin, wie sie den Datensatz zurückgeben.

$row = mysql_fetch_row($result);

Bei mysql_fetch_row wird der Datensatz als einfaches indiziertes Array zurückgegeben. Der Zugriff auf die einzelnen Felder bzw. Spalten erfolgt dann über die Spaltennummer beginnend bei 0. Ein Beispiel: $row[1] für die zweite Spalte.

$row = mysql_fetch_array($result);

Der Datensatz wird bei Verwendung von mysql_fetch_array als assoziatives Array zurückgegeben. Als Index müssen Sie dann die Spaltennamen verwenden. Beispiel: $row['autor']

$row = mysql_fetch_object($result);

Als Objekt gibt die Funktion mysql_fetch_object den Datensatz zurück. Die einzelnen Felder des Datensatzes werden dann als Eigenschaften des Objekts zur Verfügung gestellt. Die Namen der Eigenschaften richten sich nach den Spaltennamen. Ein Beispiel: $row->autor

Sobald alle Datensätze zurückgegeben worden sind, liefern alle drei Funktion FALSE zurück. Die Funktionen sind also schon fast dazu prädestiniert, in einer while-Schleife angewendet zu werden.

Wenn Ihnen die exakte Tabellenstruktur unbekannt ist, können Sie die Ergebnistabelle folgendermaßen ausgeben:

$result = mysql_query('SELECT * FROM bspbuecher');  
if($result)  
{  
  echo '<table>';  
  while($row = mysql_fetch_row($result))  
  {  
    echo '<tr>';  
    for($col = 0; $col < SizeOf($row); $col++)  
    {  
      echo "<td>$row[$col]</td>";  
    }  
    echo '</tr>';  
  }  
  echo '</table>';  
}

# Ergebnisverarbeitung bei anderen Anweisungen

Da Anweisungen wie z. B. DELETE oder INSERT kein Ergebnis liefern, können Sie den Erfolg der Anweisung erst einmal nur mit if($result) überprüfen. Dies ist jedoch in den meisten Fällen nicht ausreichend. Vor allem bei INSERT- oder UPDATE-Anweisungen möchte man häufig wissen, wie viele Datensätze von der UPDATE-Anweisung betroffen waren oder welcher Primärschlüssel einem neuen Datensatz zugewiesen wurde.

Bei INSERT-, UPDATE- oder DELETE-Anweisungen können Sie mit Hilfe der Funktion mysql_affected_rows ermitteln, wie viele Datensätze von einer Anweisung betroffen waren.

integer mysql_affected_rows([resource connection])

Die Angabe der Verbindungskennung ist optional. Wenn jedoch mehrere Verbindungen gleichzeitig geöffnet sind, sollten Sie die Verbindungskennung immer mit angeben, damit Sie auch den korrekten Wert erhalten. Bei der Verarbeitung des Wertes sind jedoch ein paar Hinweise zu beachten. Nach einer DELETE-Anweisung liefert mysql_affected_rows die Anzahl der tatsächlich gelöschten Datensätze, aber nur, wenn Sie eine WHERE-Bedingung angegeben haben. Ohne Bedingung werden alle Datensätze gelöscht, und der Rückgabewert von mysql_affected_rows entspricht 0. Auch bei einer UPDATE-Anweisung kann es zu Irritationen kommen. Denn die Funktion mysql_affected_rows liefert nur die Datensätze zurück, die auch wirklich verändert wurden. Datensätze, die zuvor schon über den neuen Wert verfügten, werden nicht geändert und werden in der Zählung auch nicht berücksichtigt.

$result = mysql_query('UPDATE bspbuecher SET verlag=2 WHERE verlag=3');  
if($result)  
{  
  $affected = mysql_affected_rows($connection);  
  echo "Es wurden $affected Datensätze verändert.";  
}

Wenn Sie neue Datensätze in eine Tabelle mit einer INSERT-Anweisung einfügen und dabei keinen Wert für eine Spalte mit der Option AUTO_INCREMENT angeben, wird automatisch ein Wert zugewiesen. Mit der Funktion mysql_insert_id lässt sich dann der automatisch zugewiesene Wert ermitteln. Der Funktion können Sie optional eine Verbindungskennung übergeben.

int mysql_insert_id([resource connection])

Wurde bei der vorherigen SQL-Anweisung kein automatischer Wert zugewiesen, liefert die Funktion 0 zurück.

# Datentypen

Das Einfügen von Daten ist eigentlich kein Problem, jedoch müssen einige Dinge beachtet werden.

# Zeichenketten

MySQL erwartet, dass Zeichenketten in einfachen Anführungsstrichen übergeben werden. Dadurch bleibt Ihnen in der Regel nichts anderes übrig, als die gesamte SQL-Anweisung in doppelte Anführungszeichen zu setzen, um die einfachen innerhalb der Anweisung oder auch für die automatische Auflösung von Variablen verwenden zu können.

$name = 'Galileo Press';  
$sql = "SELECT * FROM bspverlage WHERE name = '$name'";

Es kommt jedoch auch oft vor, dass Sie innerhalb einer Zeichenkette bestimmte Sonderzeichen verwenden möchten. Häufig werden auch einfache Anführungszeichen innerhalb von doppelten Anführungszeichen verwendet, was innerhalb von PHP natürlich zulässig ist.

$a_string = "That's tricky.";  
$sql = "INSERT INTO a_table VALUES ('$a_string')";

Auf den ersten Blick ist der Fehler nicht sofort zu erkennen. Die Variable $a_string wird bei der Zuweisung der SQL-Anweisung an $sql automatisch aufgelöst, was dazu führt, dass versucht wird, folgende Zeichenkette als Anweisung an MySQL zu übergeben:

INSERT INTO a_table VALUES ('That's tricky')

MySQL denkt nun, dass die einzufügende Zeichenkette nach That zu Ende ist, und quittiert dies mit einer Fehlermeldung, da anschließend weitere Zeichen folgen, mit denen MySQL nichts anfangen kann. Dies kann Ihnen auch mit anderen Zeichen wie z. B. " oder \\ passieren. Es wäre mühselig, nun jedes Mal die Sonderzeichen mit \\ zu entwerten. PHP hat jedoch eine Funktion auf Vorrat, die dies übernimmt: addslashes. Diese Funktion setzt vor alle Sonderzeichen, also ', ", \\ und \\0 (0-Byte-Zeichen), einen Backslash:

string addslashes(string str)

Die folgende Funktion gibt die überarbeitete Zeichenkette zurück:

$a_string = "That's tricky.";  
$sql =  
 "INSERT INTO a_table VALUES ('".addslashes($a_string)."')";

# Datums- und Zeitangaben

Ich hatte bereits angemerkt, dass es im Zusammenhang mit Datums- und Zeitangaben des Öfteren Probleme gibt, die durch die Formatierung solcher Werte bedingt sind. MySQL erwartet Datumsangaben entweder im Format JJJJTTMM oder JJJJ-TT-MM. Bei Zeitangaben akzeptiert MySQL entweder HHMMSS oder HH:MM:SS.

PHP arbeitet jedoch mit einem Zahlenwert, der die Sekunden seit dem 1.1.1970 darstellt. Am einfachsten ist die Verwendung einer MySQL-Funktion, und zwar FROM_UNIXTIME. Diese Funktion wandelt einen PHP-Zeitstempel in einen MySQL-kompatiblen Zeitstempel um.

$timestamp = time();  
$sql =  
  "INSERT INTO a_table VALUES(FROM_UNIXTIME($timestamp))";

Der PHP-Zeitstempel wird dann vor dem Einfügen in die Datenbank in das MySQL-Format umgewandelt. Dabei ist es egal, ob die Spalte vom Typ DATE, TIME oder DATETIME ist. Alternativ können Sie natürlich auch die PHP-Funktion strftime verwenden, um den PHP-Zeitstempel zuvor in einen MySQL-Zeitstempel umzuwandeln.

$timestamp = strftime("%Y%m%d",time());  
$sql = "INSERT INTO a_table VALUES($timestamp)";

Umgekehrt können Sie natürlich auch einen MySQL-Zeitstempel in einen PHP-Zeitstempel umwandeln. Auch dafür stellt MySQL eine Funktion bereit: UNIX_TIMESTAMP.

$sql = "SELECT UNIX_TIMESTAMP(date) FROM a_table";

Die Datumsangabe in der Spalte date wird nun als PHP-kompatibler Zeitstempel zurückgegeben. Darüber hinaus bietet natürlich auch PHP verschiedene Möglichkeiten, einen beliebigen Zeitstempel für PHP kompatibel zu machen. Dies ist jedoch viel umständlicher, da Sie zuvor überprüfen müssen, ob Sie einen Wert vom Typ DATE, TIME oder DATETIME erhalten, und anschließend den erhaltenen Wert Stück für Stück zerlegen müssen.

Ein Hinweis zum Schluss: Datums- und Zeitangaben werden in MySQL übrigens nicht in Anführungsstrichen notiert.

# Fehlerbehandlung

Es kann immer einmal zu Fehlern kommen. Deshalb geben alle MySQL-spezifischen PHP-Funktionen auch immer FALSE zurück, wenn ein Fehler aufgetreten ist. Den genauen Fehlergrund erfahren Sie dadurch jedoch nicht. Sie können nur feststellen, an welcher Stelle ein Fehler aufgetreten ist.

$connection = mysql_connect('localhost','user','password');  
if($connection)  
{  
  ...  
}  
else  
{  
  echo 'Verbindung konnte nicht hergestellt werden.';  
}

Zur MySQL-API gehören aber auch zwei Funktionen, die Ihnen genaue Auskunft über den Fehler geben. Dies sind mysql_errno und mysql_error.

mysql_errno ermittelt den Fehlercode, und mysql_error liefert einen entsprechenden Fehlertext. Sie sollten die Rückgabewerte der beiden Funktionen bei der Ausgabe einer Fehlermeldung zusätzlich mit ausgeben.

$connection = mysql_connect('localhost','user','password');  
if($connection)  
{  
  ...  
}  
else  
{  
  echo "Verbindung konnte nicht hergestellt werden.\n";  
  echo 'Fehler #'.mysql_errno().' – 'mysql_error()."\n";  
}

Die Verwendung dieser beiden Funktionen ist vor allem bei der Entwicklung von PHP-Scripts hilfreich, da sie Ihnen mehr Transparenz liefern und Sie feststellen können, ob der Fehler in Ihrem Script oder in MySQL zu finden ist.

# Metainformationen

Zusätzlich zu den einzelnen Datensätzen aus Abfragen können Sie jedoch auch allgemeine Informationen zu den vorhandenen Datenbanken, Tabellen und den einzelnen Strukturen erhalten. Auch dafür stellt die MySQL-API eine Reihe von Funktionen bereit.

# Datenbanken

So können Sie z. B. mit der Funktion mysql_list_dbs alle verfügbaren Datenbanken eines MySQL-Servers auflisten. Der Aufruf und das Ergebnis dieser Funktion entspricht der SQL-Anweisung SHOW DATABASES. Als Ergebnis liefert die Funktion eine Ressource. Mit mysql_fetch_row oder einer anderen Funktion, die Ergebnistabellen abarbeiten kann, können Sie die einzelnen Datenbanken dann auslesen.

resource mysql_list_dbs([resource connection])

Wenn während des Vorgangs ein Fehler aufgetreten ist, liefert die Funktion FALSE zurück. Sie können dann mit mysql_errno und mysql_error detaillierte Informationen zu dem Fehler abrufen.

$dblist = mysql_list_dbs();  
while($db = mysql_fetch_array($dblist))  
{  
  echo $db['database']."<br>\n";  
}

Die Funktion mysql_list_dbs ermittelt lediglich die Namen der Datenbanken. Wenn Sie mysql_fetch_row verwenden, genügt die Angabe des Index 0. Bei mysql_fetch_array lautet der Schlüssel database und bei mysql_fetch_object heißt die Eigenschaft database.

# Tabellen

Die MySQL-API stellt zudem die Funktion mysql_list_tables bereit, die den gleichen Zweck wie die SQL-Anweisung SHOW TABLES erfüllt. Sie ermittelt alle Tabellen, die eine Datenbank enthält, und gibt eine Ressource auf die Ergebnistabelle zurück. Diese Tabelle lässt sich ebenfalls wieder mit einer entsprechenden Funktion auslesen. Als Parameter erwartet sie auf jeden Fall den Namen der Datenbank, deren Tabellen ermittelt werden sollen.

resource mysql_list_tables(string database [, resource connection])

Die Angabe des Datenbankhandles ist wie auch bei mysql_list_dbs optional, aber notwendig, wenn Sie mehrere Verbindungen gleichzeitig geöffnet haben.

$tablelist = mysql_list_tables('bspbuecher');  
while($table = mysql_fetch_row($tablelist))  
{  
  echo $table[0]."<br>\n";  
}

Sie sollten zum Auslesen der Ergebnistabelle mysql_fetch_row verwenden, da der Name des Schlüssels bzw. der Eigenschaft bei Verwendung von mysql_fetch_array oder mysql_fetch_object ein wenig umständlich ist. Wurden die Tabellen der Datenbank bspbuecher ausgelesen, lautet der Name nämlich tables_in_bspbuecher und ändert sich dementsprechend abhängig vom Datenbanknamen.

# Felder bzw. Spalten

Die Funktion mysql_list_fields arbeitet ähnlich wie die SQL-Anweisung EXPLAIN tablename. Es gibt einen kleinen Unterschied: mysql_list_fields liefert nur die Namen der einzelnen Felder bzw. Spalten, während EXPLAIN detaillierte Informationen zur Struktur der Tabelle liefert. Es gibt jedoch weitere Funktionen, die auch diese Detailinformationen ermitteln. Als Parameter erwartet mysql_list_fields zum einen den Datenbanknamen und zum anderen einen Tabellennamen.

resource mysql_list_fields(string database, string table [, resource connection])

Wurde die Funktion erfolgreich ausgeführt, gibt sie eine Ressource auf die Ergebnistabelle zurück, andernfalls natürlich FALSE. Die Ergebnistabelle können Sie nun nicht mehr mit mysql_fetch_row, mysql_fetch_array oder mysql_fetch_object auslesen, sondern nur mit den Funktionen, die die MySQL-API dafür vorgesehen hat.

  • mysql_field_name
    gibt den Namen eines Feldes bzw. einer Spalte zurück.
  • mysql_field_type
    ermittelt den Datentyp eine Feldes.
  • mysql_field_len
    liefert die Länge eines Feldes.
  • mysql_field_flags
    gibt die gesetzten Optionen einer Spalte zurück.

Alle vier Funktionen erwarten zwei Parameter: die Ressource der Ergebnistabelle und den Index der Spalte, über die Informationen ermittelt werden sollen.

string  mysql_field_name(resource fields, integer index)  
string  mysql_field_type(resource fields, integer index)  
integer mysql_field_len(resource fields, integer index)  
string  mysql_field_flags(resource fields, integer index)

Wenn Sie Details über die Struktur einer Tabelle erfahren wollen, werden die Informationen in einer Ergebnistabelle gespeichert. Alle Spalten, die eine Tabelle besitzt, werden dann als Datensätze in die Ergebnistabelle eingefügt. Diese Datensätze enthalten dann den Namen, den Datentyp, die Feldlänge und die gesetzten Optionen. Mit dem Parameter index der vier zuvor genannten Funktionen können Sie dann die einzelnen Spalten bei 0 beginnend identifizieren.

Das nun folgende Listing bietet ein Beispiel dafür, wie die einzelnen Funktionen zusammenarbeiten.

<?php

  $connection = mysql_connect('localhost','','');
  $fields = mysql_list_fields('bspbuecher','bspbuecher');
  
  echo '<table border="1">';
  echo '<tr><th>Name</th><th>Datentyp</th><th>L�nge</th><th>Optionen</th></tr>';
  
  for($col=0; $col<mysql_num_fields($fields); $col++)
  {
    $name = mysql_field_name($fields,$col);
    $type = mysql_field_type($fields,$col);
    $len = mysql_field_len($fields,$col);
    $flags = mysql_field_flags($fields,$col);
    echo '<tr>';
    echo "<td>$name</td>";
    echo "<td>$type</td>";
    echo "<td>$len</td>";
    echo "<td>$flags</td>";
    echo '</tr>';
  }
  
  echo '</table>';
  
  mysql_close();
  
?>

Listing 5.2: Die Strukturdaten der Tabelle bspbuecher ermitteln

Ein Großteil dieses Listings besteht aus echo-Anweisungen, um die Daten auszugeben. Konzentrieren Sie sich also auf das Wesentliche:

for($col=0; $col<mysql_num_fields($fields); $col++)

Diese for-Schleife wird so lange ausgeführt, wie Datensätze in der Ergebnistabelle vorhanden sind. Optional hätte man zwar eine while-Schleife verwenden können, Sie benötigen jedoch eine Zählvariable (in diesem Fall $col), die Sie als Index an die Funktionen mysql_field_name, mysql_field_type, mysql_field_len oder mysql_field_flags übergeben. Im Anweisungsblock der Schleife werden dann die einzelnen Werte ermittelt und ausgegeben.

# Zusammenfassung

  • Verbindungen zu MySQL-Datenbanken werden mit der Funktion mysql_connect aufgebaut.
  • Die Auswahl der Datenbank erfolgt mit mysql_select_db.
  • SQL-Anweisungen können mit mysql_query ausgeführt werden.
  • Die Behandlung der Ergebnisse erfolgt abhängig von der der SQL-Anweisung: bei SELECT- und SHOW-Anweisungen mit Funktionen, die die Ergebnistabelle auslesen, und bei allen anderen Anweisungen mit mysql_affected_rows.
  • Detailinformationen über Fehler erhalten Sie mit mysql_errno und mysql_error.
  • Mit den Funktionen mysql_list_db, mysql_list_tables und mysql_list_fields können Sie alle existierenden Datenbanken, Tabellen und Felder von MySQL anfordern.
  • Die Funktionen mysql_field_name, mysql_field_type, mysql_field_len und mysql_field_flags hingegen liefern Detailinformationen zu den Feldern bzw. Spalten einer Tabelle.

# Fragen und Übungen

  1. Schreiben Sie ein PHP-Script, das die Namen aller in der Tabelle bspverlage vorhandenen Verlage in einem HTML-Dokument ausgibt.
  2. Erweitern Sie das Script aus der vorherigen Aufgabe so, dass die Namen der Verlage als Hyperlinks ausgegeben werden. Nach dem Klick auf einen der Hyperlinks sollen in einem weiteren Script die Titel und die Autoren aller Bücher des Verlags ausgegeben werden.
  3. Erweitern Sie das Script erneut. Die Buchtitel sollen nun auch als Hyperlinks ausgegeben werden. Nach einem Klick auf einen Buchtitel sollen alle Informationen zu dem Buch in einem HTML-Dokument ausgegeben werden.