DSP-Logo
previous up next
contents index
Previous: PHP & HTML Up: Einführung PHP Next: PHP & HTTP

Unterabschnitte

PHP & MySQL

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!

Syntax

allgemein

Zum Beschreiben der Syntax von PHP-Befehlen hat sich ein gewisser Standard entwickelt. Dieser hat große Ähnlichkeit mit dem anderer Programmiersprachen.

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');


mysql_connect

Syntax:
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.


mysql_close

Syntax:
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.

mysql_select_db

Syntax:
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.


mysql_query

Syntax:
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.


mysql_fetch_array

Syntax:
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, t2
Die 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"];
}
?>


mysql_fetch_row

Syntax:
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];
}
?>


mysql_error

Syntax:
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.


mysql_errno

Syntax:
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.


mysql_insert_id

Syntax:
int mysql_insert_id([resource link_identifier])
Gibt die Nummer zurück, die beim letzten INSERT dem Feld mit AUTO_INCREMENT zugewiesen wurde.


mysql_num_rows

Syntax:
int mysql_num_rows(resource result);
Gibt die Anzahl der Zeilen im Ergebnis zurück.

Tips und Tricks

Gerade beim Zusammenspiel von PHP und MySQL gibt es einige Stellen, an denen man es sich einfach machen kann, wenn man weiß, wie.

Im Folgenden sei bereits jeweils eine Datenbankverbindung hergestellt.

Abfragen mit IN

Gegeben sei ein Array von IDs, die im IN-Teil einer Abfrage auftauchen sollen. Mithilfe der PHP-Funktion implode spart man sich das händische Zusammenbauen des entsprechenden Strings.

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'";

Übung

Ergebnis-Tabelle ausgeben I

Als Vertiefung und Übung zu dem bisher gesagten eine kleine Aufgabe:
Es soll eine Funktion geschrieben werden, die das Ergebnis einer SQL-Abfrage tabellarisch darstellt. Die Ausgabe soll im Prinzip die Tabelle, die man beim MySQL-Prompt bekommt, in HTML umsetzen (inkl. Spaltennamen).

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";
?>

Tips zur Lösung

Die Aufgabe in mehreren Schritten lösen:
  1. Nur in der 1. Zeile die 1. Spalte ausgeben.
  2. Mit einer Schleife für alle Zeilen die 1. Spalte ausgeben.
  3. Mit einer 2. Schleife alle Spalten ausgeben (vorher in der Dokumentation nachsehen, mit welcher Funktion man die Spaltenanzahl abfragen kann).
  4. Als letztes noch die Spaltennamen ausgeben.

Eine Lösung befindet sich in Anhang B.2.

Ergebnis-Tabelle ausgeben II

Das Hauptprogramm aus der vorigen Aufgabe soll etwas erweitert werden. Bei meiner Vorgabe ist bis jetzt noch keine Fehlerprüfung enthalten. Was für Fehler können auftreten? Bei dem ersten Fehler soll die Fehlermeldung von MySQL ausgegeben werden, beim zweiten ``Keine Datensätze gefunden``. Das Hauptprogramm soll entsprechend erweitert werden.

Eine Lösung befindet sich in Anhang B.3.


Abfrage mit sprintf()

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.


Einfügen mit automatischer ID

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.


previous up next
contents index
Up: Einführung PHP Previous: PHP & HTML Next: PHP & HTTP

Christoph Reeg