Jetzt kommen wir zu dem Punkt, auf den wir schon die ganze Zeit hingearbeitet haben: Die Verbindung von PHP und MySQL. In diesem Kapitel werden die Befehle beschrieben. Weiter unten werden noch Befehlsfolgen für gewisse Aufgaben aufgelistet.
Hier werden jetzt Befehle von PHP und MySQL verwendet. Zwischen diesen beiden Sprachen ist streng zu trennen!
Was muß in der Syntax erklärt werden? Als erstes interessiert natürlich der Funktionsname. Da Funktionen immer was zurückgeben, interessiert auch der Rückgabetyp und last but not least muß man auch wissen, welche Parameter die Funktion erwartet (und welchen Typ sie haben müssen). Diese Informationen sind in der Syntax versteckt. Nehmen wir als Beispiel die Funktion mysql_connect(). Laut Anleitung ist die Syntax wie folgt (wegen Platzproblemen in zwei Zeilen geschrieben, eigentlich gehört alles hintereinander):
resource mysql_connect ( [string server [, string username [, string password ]]])Schauen wir uns die Syntax mal von vorne an. Das Wort resource gibt den Rückgabetyp der Funkion mysql_connect an. In den Klammern stehen dann die Parameter, wobei das string den erwarteten Typ angibt, d.h. alle drei Parameter müssen in diesem Fall vom Typ string sein. Eckige Klammern definieren jeweils einen optionalen Teil, der nur bei Bedarf angegeben werden muß. Wenn der jeweilige Parameter nicht angegeben wird, wird ein Standardwert genommen. Die genaue Beschreibung der Parameter und welche Standardwerte diese haben, wenn sie optional sind, steht in der anschließenden Beschreibung.
Die Typangabe und die eckigen Klammern werden später selbstverständlich nicht mit eingegeben. Mit allen Parametern würde der Aufruf des Befehls z.B. folgendermaßen aussehen:
$link = mysql_connect('localhost','MeinName','MeinPasswort');
resource mysql_connect ( [string server [, string username [, string password ]]])Mit mysql_connect() wird eine Verbindung zum Server geöffnet.
Wenn der zurückgegebene Wert nicht ,FALSE` ist, verlief die Verbindung erfolgreich. Bei einem zweiten Aufruf mit denselben Parametern wird keine neue Verbindung erstellt, aber es wird der `link_identifier` zurückgegeben. Der ` link_identifier` wird benötigt, um bei mehreren Verbindungen eine eindeutig bestimmen zu können.
Als `hostname` ist in unserem Fall immer localhost zu nehmen. Für ` username` und `password` sind die von uns bzw. von dir selbst zugewiesenen Werte zu nehmen.
Die Verbindung wird automatisch bei Beenden des Scripts geschlossen; sie kann aber auch mit mysql_close() explizit geschlossen werden.
bool mysql_close ( [resource link_identifier])mysql_close schließt eine bestehende Verbindung zum Server.
Es wird entweder `TRUE` bei Erfolg oder `FALSE` bei einem Fehler zurückgegeben.
Mit `link_identifier` kann explizit angegeben werden, welche Verbindung geschlossen werden soll. Wenn nichts angegeben wurde, wird die zuletzt geöffnete Verbindung geschlossen.
bool mysql_select_db ( string database_name [, resource link_identifier])Mit mysql_select_db wird die Datenbank ausgewählt, auf die sich die Anfragen beziehen soll.
Es wird entweder `TRUE` bei Erfolg oder `FALSE` bei einem Fehler zurückgegeben.
Wenn kein `link_identifier` angegeben wurde, wird die zuletzt geöffnete Verbindung zum Server benutzt.
resource mysql_query ( string query [, resource link_identifier])mysql_query sendet die SQL-Befehlsfolge `query` an den Server mit der DB, die durch den `link_identifier` festgelegt ist. Wird kein ` link_identifier` angegeben, wird die zuletzt geöffnete Verbindung genutzt.
Es wird ein sogenannter Zeiger auf das Ergebnis (result pointer) zurückgegeben. Wenn dieser (Result-)Zeiger den Wert ,FALSE` hat, gibt es einen Fehler. Mit dem Zeiger an sich kann man aber nicht viel anfangen; vielmehr benötigt man ihn, um die folgenden Funktionen nutzen zu können. Dort wird er als Parameter result übergeben.
array mysql_fetch_array(resource result [, int resulttype])Dies ist eine erweiterte Version von `mysql_fetch_row` (siehe nächste Funktion). Die Indizes des Arrays werden nicht von 0 ausgehend durchgezählt, sondern nach den Spaltennamen benannt.
Die Funktion ist in der Ausführung nur unwesentlich langsamer als mysql_fetch_row, obwohl es deutlich angenehmer zu programmieren ist.
Wenn beim Join zweier Tabellen zwei Spalten denselben Namen haben, müssen ihnen mit Hilfe der SELECT-Anweisung andere Namen gegeben werden. Beispiel:
SELECT t1.s1 AS foo, t2.s1 AS bar FROM t1, t2Die Spalte s1 der Tabelle t1 hat nun den Namen foo und s1 aus t2 hat den Namen bar.
Das optionale zweite Argument result_type in mysql_fetch_array ist eine Konstante und kann die folgenden Werte annehmen: MYSQL_ASSOC, MYSQL_NUM und MYSQL_BOTH.
Bei MYSQL_NUM bekommt das zurück gegebene Array einen durchnumerierten Index, d.h. mysql_fetch_array verhält sich genauso wie mysql_fetch_row. Bei MYSQL_ASSOC werden die Spaltennamen als Index des Arrays genutzt und bei MYSQL_BOTH (was auch der Standard ist) gibt es beide Indizes.
<?php mysql_connect($host,$user,$password); mysql_select_db("database"); $result = mysql_query("SELECT user_id, fullname FROM users"); while($row = mysql_fetch_array($result)) { echo $row["user_id"]; echo $row["fullname"]; } ?>
array mysql_fetch_row(resource result)Holt eine Zeile aus der DB-Abfrage, gibt diese als Array zurück und setzt den Result-Zeiger auf die nächste Zeile. Für `result` muß der Rückgabewert (=Zeiger) der `mysql_query`-Funktion genommen werden.
Dasselbe Beispiel wie bei mysql_fetch_array:
<?php mysql_connect($host,$user,$password); mysql_select_db("database"); $result = mysql_query("SELECT user_id, fullname FROM users"); while($row = mysql_fetch_row($result)) { echo $row[0]; echo $row[1]; } ?>
string mysql_error([resource link_identifier])Gibt die Fehlermeldung des letzten SQL-Befehls zurück. Wenn es keinen Fehler gab, wird nichts zurück gegeben. Wird kein `link_identifier` angegeben, wird die zuletzt geöffnete Verbindung genutzt.
int mysql_errno([resource link_identifier])Gibt die Fehlernummer des letzten SQL-Befehls zurück. Wenn es keinen Fehler gab, wird 0 zurückgegeben. Wird kein `link_identifier` angegeben, wird die zuletzt geöffnete Verbindung genutzt.
int mysql_insert_id([resource link_identifier])Gibt die Nummer zurück, die beim letzten INSERT dem Feld mit AUTO_INCREMENT zugewiesen wurde.
int mysql_num_rows(resource result);Gibt die Anzahl der Zeilen im Ergebnis zurück.
Im Folgenden sei bereits jeweils eine Datenbankverbindung hergestellt.
Denkbar wäre etwa folgende Abfrage zum Löschen aller Datensätze, deren IDs im übergebenen Array vorkommen. Dieses Array, nennen wir es einmal delIDs, könnte z.B. von einem Formular mit Checkboxen wie in 9.3 beschrieben stammen: Auf einer Übersichtseite, auf die hier nicht näher eingegangen wird, könnten alle oder bestimmte Datensätze in Tabellenform nebst je einer Checkbox angezeigt werden, wobei die VALUE-Attribute der Checkboxen genau den IDs der Datensätze entsprächen.
mysql_query("DELETE FROM tabelle WHERE ID IN (".implode(',', $delIDs).")");
Wenn die Werte keine Integers sondern Strings sind, kommt man aber wohl kaum um einen kompletten Durchlauf des Arrays herum:
foreach ($ids as $key=>$id) $ids[$key] = "'$id'";
Wenn man zum Beispiel am MySQL-Prompt alle Mitarbeiter abfragen will, kommt folgende Ausgabe zustande:
mysql> select * from Mitarbeiter; +-----+------+-------+----------------+------------+--------------+ | MNr | VNr | AbtNr | Name | GebDat | Telefon | +-----+------+-------+----------------+------------+--------------+ | 1 | NULL | 3 | Christoph Reeg | 1979-05-13 | NULL | | 2 | 1 | 1 | junetz.de | 1998-03-05 | 069/764758 | | 3 | 1 | 1 | Uli | NULL | NULL | | 4 | 3 | 1 | JCP | NULL | 069/764758 | | 5 | 1 | 2 | Maier | NULL | 06196/671797 | | 6 | 5 | 2 | Meier | NULL | 069/97640232 | +-----+------+-------+----------------+------------+--------------+ 6 rows in set (0.00 sec) mysql>
Um das in einer HTML-Tabelle darzustellen, ist folgender (vereinfachter) HTML-Code notwendig:
<html> <body> <table> <tr> <th>MNr</th> <th>VNr</th> <th>AbtNr</th> <th>Name</th> <th>GebDat</th> <th>Telefon</th> </tr> <tr> <td>1</td> <td></td> <td>3</td> <td>Christoph Reeg</td> <td>1979-05-13</td> <td></td> </tr> <tr> <td>2</td> <td>1</td> <td>1</td> <td>junetz.de</td> <td>1998-03-05</td> <td>069/764758</td> </tr> <tr> <td>3</td> <td>1</td> <td>1</td> <td>Uli</td> <td></td> <td></td> </tr> <tr> <td>4</td> <td>3</td> <td>1</td> <td>JCP</td> <td></td> <td>069/764758</td> </tr> <tr> <td>5</td> <td>1</td> <td>2</td> <td>Maier</td> <td></td> <td>06196/671797</td> </tr> <tr> <td>6</td> <td>5</td> <td>2</td> <td>Meier</td> <td></td> <td>069/97640232</td> </tr> </table> </body> </html>
Als kleine Hilfe hier das Rahmenprogramm für die Funktion:
<?php $db_host = "localhost"; $db_user = "cr"; $db_pass = "123"; $datab = "cr"; function print_result_table($result){ // hier das richtige schreiben } // Hauptprogramm /* Verbindung zur Datenbank aufbauen */ $db = @mysql_connect($db_host,$db_user,$db_pass) or die(mysql_error()); @mysql_select_db($datab,$db) or die(mysql_error()); /* HTML-Startcode ausgeben */ echo "<html>\n<body>\n"; /* SQL-Abfrage */ $result = @mysql_query("SELECT * FROM Mitarbeiter"); print_result_table($result); /* HTML-Endcode ausgeben */ echo "</body>\n</html>\n"; ?>
Eine Lösung befindet sich in Anhang B.2.
Eine Lösung befindet sich in Anhang B.3.
Auch in diesem Beispiel wird obige Tabelle benutzt. Die Zeile ,,/* SQL-Abfrage */`` und die folgende werden jedoch nun wie folgt verändert.
... $was = "Name"; $monat = 5; $jahr = 1979; /* SQL-Abfrage */ $result = @mysql_query( sprintf("SELECT %0\$s FROM Mitarbeiter WHERE GebDat LIKE '%2\$02d-%3\02d-%'", $was, $monat, $jahr ) ); ...
In diesem Programmabschnitt sind sechs Fehler versteckt. Wer findet sie? Auflösung in Anhang B.4.
Nun etwas neues: Es soll in zwei Tabellen eingefügt werden, wobei die ID der ersten Einfügeoperation für die zweite benötigt wird. Konkret soll der Mitarbeiter ,, Jens`` eingefügt werden, der direkt Christoph Reeg unterstellt ist, in der Verwaltung arbeitet und am 26.5.1981 Geburtstag hat. Diesem Mitarbeiter unterstellen wir wiederum einen Helfer namens Kile, der in der EDV arbeitet. Zu beachten ist, daß beim Einfügen keine Mitarbeiter-Nummer vergeben werden sollen; das soll MySQL selbst machen (die MNr ist ein AUTO_INCREMENT-Feld). Alle hier nicht angegebenen Werte sollen NULL sein.
Eine mögliche Lösung findet sich in Anhang B.5. Die Verbindungsdaten für MySQL seien dieselben wie bei 10.3.1. Die vorgegebenen Tabellen finden sich unter A.2.