|

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