Werbung einblenden Werbung ausblenden


Home / Tutorials / mysql Handbuch / mysql mit PHP ansteuern

Zugriff auf relationale Datenbanken mit PHP
Daten in eine Tabelle einfügen
Daten in einer Tabelle suchen
Auf ein einzelnes Feld zugreifen
Die Anzahl der von einem sql-statement betroffenen Datesätze ermitteln
Sich die komplette Struktur einer Datenbank zeigen lassen
Eine Tabelle löschen

Zugriff auf relationale Datenbanken mit PHP

Vorraussetzung für das Verständnis dieses Kapitels sind Kenntnisse in sql und ein Überblick über die Funktionsweise von mysql. Unter Umständen sollte man also das Kapitel Kurzeinführung in mysql lesen. Die mysql-Datenbank muss installiert und hochgefahren worden sein. Um die Skripte, die hier vorgestellt werden laufen zu lassen, benötigt man eine mysql-Datenbank testofix, die man so einrichten kann:

<?
$verbinden1="127.0.0.1";
$verbinden2="";
$verbinden3="";
mysql_connect($verbinden1,$verbinden2,$verbinden3);
mysql_create_db("testofix");
print "Datenbank wurde eingerichtet";
?>

Wer nachprüfen will, ob das tatsächlich funktioniert hat, der kann jetzt unter c:/mysql/data nachschauen, ob sich dort ein Ordner mit dem Namen testofix befindet. Der naheliegende Gedanke, dass man diesen Ordner auch "per Hand" hätte einrichten können, ist zutreffend. Wir können mit der Datenbank aber nur was anfangen, wenn sie auch zumindest eine Tabelle hat. Foglich müssen wir jetzt eine Tabelle einrichten.

<?
$a="127.0.0.1";
$b="";
$c="";
$d="testofix";
#$a="db.puretec.de";
#$b="551433";
#$c="c2813839";
#$d="db551433";
mysql_connect($a,$b,$c);
mysql_select_db($d);
mysql_query("create table testomat (Familienname char(80),
Telefon char(50),Gewicht dec(5,2),Lebenszeit int(5),
Datum timestamp(6), count int(4) NOT NULL AUTO_INCREMENT,
Primary Key(count))");
mysql_close();
print "Tabelle testomat wurde kreiert";
?>

Für Details hinsichtlich Datentypen (int, dec,char),timestamp etc., siehe Kurzeinführung in mysql . Wer wissen will, ob das funktioniert hat, der muss in den Ordner c:/mysql/data/testofix gehen. Dort müssten drei Dateien eingerichtet worden sein: testomat.frm, testomat.MYD, testomat.MYI. Warum es drei sind und was sie tun, interessiert eigentlich nicht weiter, weil direkt mit diesen Dateien nie gearbeitet wird. Die Datei testomat.MYI hält die Indices, die Datei testomat.MYD die eigentlichen Daten und die Datei testomat.frm die Tabellenstruktur. Aber wie gesagt, mit diesen Dateien hat man direkt nie was zu tun. Aus Gründen der Portabilität, sollte man alle Werte, die zum Aufbau der Verbindung zur Datenbank benötigt werden, in Variablen abspeichern. In diesem Skript sind die Werte, die beispielhaft die Werte für eine Internetverbindung zeigen, mit einem Gartenzaun auskommentiert. Die Zeile
mysql_connect($a,$b,$c);

baut dann die Verbindung zum mysql Server aufgebaut. Mit
mysql_select_db($d);

wird dann die entsprechende Datenbank ausgewählt. Die Funktion
mysql_quere(irgendein select statemnt);

führt dann innerhalb der zuvor ausgewählten Datenbank das sql statement aus. Schlussendlich wird mit
mysql_close();

die Datenbank geschlossen. Praktisch alle Zugriffe auf eine mysql Datenbank laufen nach diesem Schema ab.
mysql_connect(virtuelle Adresse des mysql Datenbankservers, Userid,Password);
mysql_select_db(Angabe der entsprechenden Datenbank);
mysql_query(irgendein sql statement);
mysql_close();

Dieses simple Schema deckt eigentlich fast alles ab. Das einzige was sich ändert, ist das sql-Statement.

Daten in eine Tabelle einfügen

Ist die Tabelle eingerichtet, können in die Tabelle Werte eingetragen werden:

<?
$a="127.0.0.1";
$b="";
$c="";
$d="testofix";
mysql_connect($a,$b,$c);
mysql_select_db($d);
mysql_query("insert into testomat (Familienname,Telefon, Gewicht,Lebenszeit)
values('Andres Ehmann','030-47301388','73.45','36')");
mysql_close();
print "Daten wurden eingetragen";
?>

Es ist klar, dass der Skript nur laufen kann, wenn die mysql Datenbank hochgefahren wurde.

Daten in einer Tabelle suchen

Es wäre jetzt interessant zu wissen, ob die Daten tatsächlich eingetragen wurden. Das kann man mit folgendem Skript feststellen:

<?
$a="127.0.0.1";
$b="";
$c="";
$d="testofix";
mysql_connect($a,$b,$c);
mysql_select_db($d);
$zeiger=mysql_query("select * from testomat");
$werte=mysql_fetch_array($zeiger);
print "Name: {$werte[0]} <br>";
print "Telefon:{$werte[1] }<br>";
print "Gewicht:{$werte[2]} <br>";
print "Lebenszeit:{$werte[3]} <br>";
print "Datum:{$werte[4] } <br>";
print "Zähler:{$werte[5]} <br>";
mysql_close();
?>

Das liefert, wenn der Skript, der die Daten einspeist bereits ausgeführt wurde, folgendes Ergebnis:

Name: Andres Ehmann
Telefon:030-47301388
Gewicht:73.45
Lebenszeit:36
Datum:021201
Zähler:1

Wir bemerken eine Änderung. Das Ergebnis der Ausführung des sql-statements wird an einen Zeiger übergeben, der wiederum auf den Speicherplatz zielt, wo der Array gehalten wird, der die Ergebnisse hat, also jedes Element des Arrays ist der Inhalt einer Spalte in der entsprechenden Zeile. Die geschweifte Klammer brauchen wir, weil PHP sonst innerhalb der Anführungsstriche Arraywerte nicht ausliest, bzw. PHP bringt dann eine Fehlermeldung. Wer will, kann sich die Ergebnisse auch über einen associative array, siehe Arrays und Hashes, zeigen lassen. Hierbei ist der Index des Arrays der Spaltenname, der Wert der Inhalt der entsprechenden Spalte an der entsprechenden Stelle.

<?
$a="127.0.0.1";
$b="";
$c="";
$d="testofix";
mysql_connect($a,$b,$c);
mysql_select_db($d);
$zeiger=mysql_query("select * from testomat");
$werte=mysql_fetch_array($zeiger);
print "Name: {$werte['Familienname']} <br>";
print "Telefon:{$werte['Telefon'] }<br>";
print "Gewicht:{$werte['Gewicht']} <br>";
print "Lebenszeit:{$werte['Lebenszeit']} <br>";
print "Datum:{$werte['Datum'] } <br>";
print "Zähler:{$werte['count']} <br>";
mysql_close();
?>

Wie also deutlich zu sehen, unterstützt die Funktion mysql_fetch_array sowohl "normale" Arrays als auch associative Arrays. Dies ist bei der Funktion mysql_fetch_row nicht der Fall, sie unterstützt nur nummerische Arrays, was den Verdacht nahe legt, dass sie eigentlich unnötig ist. Das folgende funktioniert noch:

<?
$a="127.0.0.1";
$b="";
$c="";
$d="testofix";
mysql_connect($a,$b,$c);
mysql_select_db($d);
$zeiger=mysql_query("select * from testomat");
$werte=mysql_fetch_row($zeiger);
print "Name: {$werte[0]} <br>";
print "Telefon:{$werte[1] }<br>";
print "Gewicht:{$werte[2]} <br>";
print "Lebenszeit:{$werte[3]} <br>";
print "Datum:{$werte[4] } <br>";
print "Zähler:{$werte[5]} <br>";
mysql_close();
?>

Aber dies hier nicht:

<?
$a="127.0.0.1";
$b="";
$c="";
$d="testofix";
mysql_connect($a,$b,$c);
mysql_select_db($d);
$zeiger=mysql_query("select * from testomat");
$werte=mysql_fetch_row($zeiger);
print "Name: {$werte['Familienname']} <br>";
print "Telefon:{$werte['Telefon'] }<br>";
print "Gewicht:{$werte['Gewicht']} <br>";
print "Lebenszeit:{$werte['Lebenszeit']} <br>";
print "Datum:{$werte['Datum'] } <br>";
print "Zähler:{$werte['count']} <br>";
mysql_close();
?>

So weit so nett. Nutzen tut uns das allerdings fast garnichts, weil wir in der Regel nicht einen Datensatz als Treffer haben, sondern beliebig viele. Um zu zeigen, wie man beliebig viele Datensätze aus einer mysql Datenbank rausfischt, müssen wir erstmal ein paar Datensätze in die DB schreiben. Das können wir mit diesem Skript machen:

<?
$a="127.0.0.1";
$b="";
$c="";
$d="testofix";
$namen=array(
"name1"=>array("Joschka Fischer","089949944","78.44","55"),
"name2"=>array("Helmuth Kohl","0303433454","150.89","70"),
"name3"=>array("Gerhadt Schröder","03039533","89.55","62")
);
mysql_connect($a,$b,$c);
mysql_select_db($d);
foreach ($namen as $wert)
{
mysql_query("insert into testomat (Familienname,Telefon,Gewicht,Lebenszeit)
values ('{$wert[0]}','{$wert[1]}','{$wert[2]}','{$wert[3]}')");
}
mysql_close();
print "Daten wurden eingespeist";
?>

Nachdem wir diesen Skript ausgelöst haben, sieht unsere Datenbank so aus.

mysql> select * from testomat;

Familienname Telefon Gewicht Lebenszeit Datum count
Andres Ehmann 030-47301390 73.45 36 021201 1
Joschka Fischer 089949944 78.44 55 021201 2
Helmuth Kohl 0303433454 150.89 70 021201 3
Gerhadt Schröder 03039533 89.55 62 021201 4

4 rows in set (0.00 sec)
mysql>

Nachdem wir Daten eingespeist haben, können wir zu unserer Ursprungsfrage zurückkommen. Wie holt man mehrere Zeilen aus einer mysql-Datenbank. Hier ein Skript, der genau das tut:


<?
$a="127.0.0.1";
$b="";
$c="";
$d="testofix";
mysql_connect($a,$b,$c);
mysql_select_db($d);
$zeiger=mysql_query("select * from testomat");
while($werte=mysql_fetch_array($zeiger))
{
print "Name: {$werte['Familienname']} <br>";
print "Telefon:{$werte['Telefon'] }<br>";
print "Gewicht:{$werte['Gewicht']} <br>";
print "Lebenszeit:{$werte['Lebenszeit']} <br>";
print "Datum:{$werte['Datum'] } <br>";
print "Zähler:{$werte['count']} <br>";
}
mysql_close();
?>

Das Ergebnis sieht dann so aus.

Name: Andres Ehmann
Telefon:030-47301388
Gewicht:73.45
Lebenszeit:36
Datum:021201
Zähler:1
Name: Joschka Fischer
Telefon:089949944
Gewicht:78.44
Lebenszeit:55
Datum:021201
Zähler:2
Name: Helmuth Kohl
Telefon:0303433454
Gewicht:150.89
Lebenszeit:70
Datum:021201
Zähler:3
Name: Gerhadt Schröder
Telefon:03039533
Gewicht:89.55
Lebenszeit:62
Datum:021201
Zähler:4

Wie deutlich zu sehen, musste nicht viel verändert werden. Wir haben lediglich den mysql_fetch_array-Befehl in eine while-Schleife eingebunden. Solange dieser nicht undef zurückgibt, was erst der Fall ist, wenn keine Daten mehr vorhanden sind, ist die Bedingung der while-Schleife true, folglich wird eine Zeile nach der anderen an den Array $werte übergeben und ausgedruckt. Eine Alternative zu mysql_fetch_array ist mysql_object, wenn auch in objektorientierter Schreibweise.

<?
$a="127.0.0.1";
$b="";
$c="";
$d="testofix";
mysql_connect($a,$b,$c);
mysql_select_db($d);
$zeiger=mysql_query("select * from testomat");
while ( $test=mysql_fetch_object($zeiger))
{
print $test->Familienname."<br>";
print $test->Telefon."<br>";
print $test->Gewicht."<br>";
print $test->Lebenszeit."<br>";
}
?>

Auf ein einzelnes Feld zugreifen

Wer von einer bestimmten Zeile nur bestimmte Spalten sehen will, der sollte das von vorneherein im sql statement angeben.
select Gewicht from testomat

Alternativ hätte man auch die Möglichkeit über mysql_result bestimmte Spalten abzugreifen. Diese Vorgehensweise wird aber im allgemeinen nicht empfohlen.

<?
$a="127.0.0.1";
$b="";
$c="";
$d="testofix";
mysql_connect($a,$b,$c);
mysql_select_db($d);
$zeiger=mysql_query("select * from testomat");
for ($i=0;$i<mysql_num_rows($zeiger);$i++)
{
print mysql_result($zeiger,$i,"testomat.Gewicht")."<br>";
}
?>

Im Gegensatz zur Funktion mysql_fetch_array rückt die Funktion mysql_num_rows auch nicht weiter zum nächsten Datensatz. Baut man sie ein in eine while-Schleife, bringt sie immer nur den ersten Datensatz, den dafür aber bis in alle Unendlichkeit. Also, das funktionniert nicht und man sollte es auch nicht ausprobieren.

<?
$a="127.0.0.1";
$b="";
$c="";
$d="testofix";
mysql_connect($a,$b,$c);
mysql_select_db($d);
$zeiger=mysql_query("select * from testomat");
while ( $test=mysql_result($zeiger,$i,"testomat.Familienname"))
{
print "$test<br>";
}
?>

Die Anzahl der von einem sql-statement betroffenen Datesätze ermitteln

Während sich mit, wie oben bereits gezeigt, mit mysql_num_rows die Anzahl der gefundenen Datensätze ermitteln läßt, kann man mysql_affected rows die Anzahl der Datensätze ermitteln, die durch einen update oder delete-Befehl geändert bzw. gelöscht wurden.

<?
$a="127.0.0.1";
$b="";
$c="";
$d="testofix";
mysql_connect($a,$b,$c);
mysql_select_db($d);
$zeiger=mysql_query("update testomat set Gewicht=82.34 where Familienname like '%Schröder%'");
print mysql_affected_rows();
mysql_close();
?>

Überraschend ist, dass diese Funktion nicht zählt, wenn der neue Wert dem alten entspricht. Die Funktion mysql_affected rows() bezieht sich immer auf den sql-statement unmittelbar vorher.

Sich die komplette Struktur einer Datenbank zeigen lassen

Wer so ein Programm wie das berühmte phpmyadmin nachprogrammieren will, der muss es schaffen, die komplette Struktur einer Datenbank, das heisst alle Tabellen und von diesen wiederum alle Spalten mit den dazugehörigen Attributen (Datentyp, Länge, Index, primary key, default Werte etc. ) auszulesen. Man kann dem user nur dann anbieten, die Struktur zu ändern, wenn er die ursprüngliche Struktur sieht. Die komplette Struktur einer Datenbank kann man mit diesem kleinen Skript auslesen.

<?
$A="127.0.0.1";
$B="";
$C="";
$D="testofix";
MYSQL_CONNECT($A,$B,$C);
MYSQL_SELECT_DB($D);
$TABELLE=MYSQL_LIST_TABLES($D);

FOR ($I=0;$I<MYSQL_NUM_ROWS($TABELLE);$I++)
{
PRINT "<br><BR>";
print $tabellenname=mysql_tablename($tabelle,$i);
print "<BR>..............................................".
" ......................................................<BR>";
$tabellenspalten= mysql_list_fields($d,$tabellenname);
for($e=0;$e<MYSQL_NUM_FIELDS($TABELLENSPALTEN);$E++)
{
PRINT "<font color=blue>Name der Spalte:"
.mysql_field_name($tabellenspalten,$e)."</FONT><BR>";
print "Type der Spalte:".mysql_field_type($tabellenspalten,$e)."<BR>";
print "Länge der Spalte:". mysql_field_len($tabellenspalten,$e)."<BR>";
print "Angaben zu Index, Schlüssel etc.:". mysql_field_flags($tabellenspalten,$e)."<BR>";
}
}
mysql_close();
?>

Das ist jetzt ein bisschen komplexer, schauen wir uns das genauer an. Mit
$tabelle=mysql_list_tables($d);

setzen wir einen Zeiger auf den Array, der alle Tabellen in der Datenbank testofix hält. Leider lässt sich dieser Array nicht so ohne weiteres mit mysql_fetch_array auslesen, weil es sich bei diesem Array wohl um einen nummerischen Array handelt. Wir müssen also die Funktion
mysql_tablename

dazwischenschieben, und erstmal den eigentlichen Namen der Tabelle ermitteln. Die Funktion mysql_tablename erwartet zwei Parameter: den Zeiger auf den Array der alle Tabellen hält und den Index der konkreten Tabelle, deren Namen wir haben wollen. Den Index wiederum können wir ermitteln, indem wir mit mysql_num_rows die Anzahl der Elemente dieses Arrays ermitteln (also des Arrays, der alle Tabellen dieser Datenbank hält) und mit diesem Wert dann eine for-Schleife laufen lassen. Von jeder Tabelle wiederum müssen wir noch ermitteln, wieviele Spalten sie hat. Die Funktion
mysql_list_fields

verlangt wiederum zwei Parameter. Den Zeiger auf die Datenbank und den Tabellennamen, letzteren haben wir ja gerade eben ermittelt. Damit haben wir den Zeiger auf einen Array, der alle Spalten der Tabelle hält. Mit den Funktionen mysql_field_name, mysql_field_type, mysql_field_len und mysql_field_flag können wir dann zu jeder Spalte die entsprechenden Informationen rausfischen. Will man sich jetzt noch alle Datenbanken anschauen, sieht das so aus:

<?
$a="127.0.0.1";
$b="";
$c="";
$d="testofix";
$zeiger = mysql_connect($a,$b,$c);
$datenbanken_zeiger = mysql_list_dbs($zeiger);

while($datenbank=mysql_fetch_array($datenbanken_zeiger))
{
print $datenbank[0]."<br>";
}
mysql_close();
?>

Damit wird es dann möglich, einen Skript zu schreiben, der alle Datenbanken und alle darin enthaltenen Tabellen mit allen Spalten und den dazugehörigen Werten auszulesen.

<?
$a="127.0.0.1";
$b="";
$c="";
$d="testofix";
$zeiger = mysql_connect($a,$b,$c);

$datenbanken_zeiger = mysql_list_dbs($zeiger);

while($datenbank=mysql_fetch_array($datenbanken_zeiger))
{
print "<font color=red size=5>{$datenbank[0]}</font><br>";
$tabelle=mysql_list_tables($datenbank[0]);

for ($i=0;$i<mysql_num_rows($tabelle);$i++)
{
print "<br><br>";
print $tabellenname=mysql_tablename($tabelle,$i);
print "<br>.................................................".
"...................................................<br>";
$tabellenspalten= mysql_list_fields($datenbank[0],$tabellenname);
for($e=0;$e<mysql_num_fields($tabellenspalten);$e++)
{
print "<font color=blue>Name der Spalte:".mysql_field_name($tabellenspalten,$e)."</font><br>";
print "Type der Spalte:".mysql_field_type($tabellenspalten,$e)."<br>";
print "Länge der Spalte:". mysql_field_len($tabellenspalten,$e)."<br>";
print "Angaben zu Index, Schlüssel etc.:". mysql_field_flags($tabellenspalten,$e)."<br>";
}
}
}
mysql_close();
?>

Um alle Spalten, aller Tabellen aller Datenbanken zu ermitteln, muss man lediglich das vorstehende Programm so abändern, dass das vorstehende Programm in einer while-Schleife eingebunden wird, die alle Datenbanken ausliest. Fazit: Irgendwie ist das kompliziert. Der Ansatz von Perl, das über Referenzen zu lösen, ist auf jeden Fall nicht komplizierter, so man sich denn mit das Konzept der Referenzen klar gemacht hat.

Eine Tabelle löschen

Um eine Tabelle zu löschen, verwendet man einfach den entsprechenden sql Befehl:

<?
$a="127.0.0.1";
$b="";
$c="";
$d="testofix";
mysql_connect($a,$b,$c);
mysql_select_db($d);
mysql_query("drop table himbeere");
mysql_close();
print "Tabelle himbeere wurde gelöscht";
?>

Es ist klar, dass dieser PHP-Schnipsel nur Sinn macht, wenn eine Tabelle himbeere tatsächlich existiert. Ob sie dann tatsächlich gelöscht wurde, läßt sich mit dem mysql Befehl show tables überprüfen.

mysql> show tables;

Tables_in_testofix
testomat

1 row in set (0.00 sec)
mysql>

Eine ganze Datenbank löschen

Zum löschen einer Datenbank gibt es den Befehl mysql_drop_db.

<?
$a="127.0.0.1";
$b="";
$c="";
$d="testofix";
mysql_connect($a,$b,$c);
mysql_drop_db("testofix");
mysql_close();
print "Die Datenbank testofix wurde gelöscht";
?>

Da wir, nachedem wir diesen Skript ausgelöst haben, keine Datenbank mehr haben, mit der wir testen können, sollten wir das Kapitel beenden.

vorhergehendes Kapitel