Zugriff auf eine mysql-Datenbank mittels php |
|
mysql von latin1 auf utf-8 umstellen
Ich weiß nicht, wer auf das schmale Brett gekommen ist einen mysql-Server unter Linux mit dem Windows-ähnlichem Zeichensatz latin1 als Standard-Zeichensatz zu kompilieren und ob sich das in Zukunft mal bessert, aber bei meiner Installation von mysql unter Debian lenny war es leider so. Und dabei ist der Standard-Zeichensatz von Linux und mitterweile auch für Webseiten im Internet UTF-8. Welcher Zeichensatz unter mysql verwendung findet, kann man mittels des Kommandozeilen-Tools mysql herausfinden. Dazu loggt man sich mittels mysql -u root -p auf dem mysql-Server ein und gibt am Eingabe-Prompt den Befehl status ein. Steht in der Ausgabe |
|
|
|
Der Zusatz skip-character-set-client-handshake schaltet die Aushandlung zwischen Clients und Server ab und somit nimmt der Server per Default den angegebenen UTF-8-Zeichensatz. mysql-Datenbank einrichten mittels phpmyadmin Nachdem wir nun den korrekten Zeichensatz haben, beginnen wir mit dem Erstellen unserer Datenbank. Dazu bedienen wir uns des Tools phpmyadmin, welches man mittels eines Browsers und der url http://localhost/phpmyadmin/ aufruft. Als Login verwenden wir den Benutzernamen root und das Paßwort, welches man bei der Installation von mysql vergeben hat. Im Feld "Neue Datenbank anlegen" |
|
kann man den Namen der Datenbank vergeben. Als nächsten Schritt kann man eine neue Tabelle erstellen und die Anzahl der Spalten festlegen. Nennen wir unsere Tabelle mal schlicht "liste" und geben wir ihr 3 Spalten. |
|
Anschließend kann man die einzelnen Spalten benennen und den Datentyp vergeben. Unsere erste Spalte erhält den Namen id und wird ein automatischer Zähler, welcher auch als Primärschlüssel dient. Dazu wählen wir den Datentyp INT, wählen im Dropdown-Menü "auto_increment" und setzen den Punkt für Primärschlüssel. Die zweite Spalte nennen wir hersteller und die Dritte typ. Diese Spalten sind vom Typ VARCHAR, welcher eine begrenzte Anzahl von Zeichen zuläßt (siehe Länge). In unserem Fall 30 Zeichen. | |
Nach einem Klick auf Speichern ist das Gerüst unserer Datenbank fertig eingerichtet und bereit zur Verwendung. Nun geht es an die Verknüpfung mittels php. Datensätze eintragen mittels php - einfache Form Zuerst erstellen wir eine eigene php-Datei die die Verbindungsdaten enthält. Diese Datei wird später mittels include in unser Eingabeformular eingebunden. Es ist aus zwei Gründen sinnvoll die Verbindungsdaten in eine eigene Datei auszulagern. Einmal kann man sie dann für jede Aufgabe, ob eintragen, löschen oder abrufen immer wieder verwenden und zum Anderen kann man sie in ein eigenes Verzeichnis verschieben, daß man mittels einer htaccess-Datei und deny from all (siehe vorheriges Kapitel) gegen unbefugten Zugriff schützen kann. Immerhin steht in der Datei das Paßwort für die Datenbank im Klartext drin. Die Datei speichern wir unter dem Namen zugriff.inc.php und hat folgenden Inhalt: |
|
|
|
Die Variablen sind natürlich selbsterkärend, bzw. steht die Erklärung als Kommentar dahinter. Mittels mysql_connect wird versucht eine Verbindung zur Datenbank aufzubauen. Sollte dies fehlschlagen, weil der Benutzername oder das Passwort falsch sind, wird mittels die die Fehlermeldung "Verbindung fehlgeschlagen" ausgegeben. Mit mysql_select_db wird versucht die Datenbank zu öffnen. Schlägt auch das fehl, weil die Datenbank nicht gefunden wurde, wird ebenfalls eine Meldung "Die Datenbank existiert nicht" ausgegeben. Nun zu unserem Eingabe-Formular. Für die Eingabe der Daten benutzen wir das form-Tag, also simplen HTML-Code. Mittels dieses Tags kann man eigene Eingabeformulare für Datenbanken entwerfen. Unsere Datei hat folgenden Inhalt: |
|
|
|
Die Datei speichern wir unter dem Namen index.php ab. Unser Formular geht von <form> bis </form> und besteht aus 3 Formularelementen. Zwei Texteingabezeilen (input type="text") mit einer Länge und maximalen Eingabe von 30 Zeichen und einem sogenannten submit-Button, welcher die Formulardaten abschickt. Sehr wichtig ist die Bezeichnung name für alle Elemente, denn das was man in die Textfelder eingibt, wird nach dem drücken auf den submit-Button unter der Namensangabe als Variablenwert gespeichert und ist so mittels php abrufbar. Sogar der submit-Button bekommt nach dem drücken einen Variablen-Wert. Es ist die value-Angabe. Die Option action legt das Folge-Dokument fest, welches beim Klick auf den submit-Button aufgerufen wird. Diesem Dokument werden mit dem Aufruf die generierten Variablen übergeben. In unserem Fall ist es dasselbe Dokument, damit natürlich der php-Code im unteren Teil ausgeführt wird. Die Option method legt die Methode der Variablenübergabe fest. Es gibt post und get. Der Unterschied besteht darin, daß bei get alle Variablen an die url angehängt werden, was bei vielen Variablen zu einer sehr langen url führt. Der Vorteil ist, daß diese url und somit die Variablen gespeichert werden kann. Der Nachteil ist, daß urls eine begrenzte Länge haben, also funktioniert bei zuviel Variablen die url nicht mehr. Das ist auch schon der ganze HTML-Code der hier noch für eine bessere Formatierung in eine Tabelle gepackt wurde, welche sich innerhalb unseres Formulars befindet. Da wir in unserem Beispiel lediglich eine Tabellenzelle haben, könnte sich das Formular auch innerhalb der Tabelle befinden. Wo ist der Unterschied? Befindet sich ein Formular innerhalb einer Tabelle, muß es innerhalb einer Tabellen-Zelle (innerhalb eines <td>-Elements) abgeschlossen sein. Bei einer Tabelle mit mehreren Zellen entstehen dadurch viele unabhängige Formulare. Möchte man lediglich ein formatiertes Formular haben, muß die Tabelle wie hier innerhalb des Formulars sein!
Nach dem HTML-Code folgt der php-Code. Eingeleitet wird php mittels <?php und beendet mit ?>. Alles dazwischen wird als php-Befehle interpretiert. Die allererste Zeile enthält die if-Abfrage isset($_GET["aufnehmen"]), welche verhindert daß die php-Befehle sofort beim Seitenaufbau ausgeführt werden und somit schon Eintragungen in die Datenbank vorgenommen werden (welche natürlich nur leere Felder enthalten würden, da ja noch keine Variablen generiert wurden). Wie schon erwähnt hat unser submit-Button ungedrückt noch keinen Variablen-Wert und bekommt nach dem drücken den Wert von value. Mit isset (is set=ist gesetzt) wird abgefragt, ob die Variable einen Wert enthält, ergo ob der Button gedrückt wurde. Folglich wird der folgende php-Code nur ausgeführt, wenn der Button gedrückt wurde. Mittels include werden die Verbindungsdaten in das Dokument eingebunden. Danach erfolgt die Übergabe der html-Variablen in php-Variablen mittels $_POST. Anschließend wird der Einfügebefehl für die Datenbank in der Variablen $sql abgelegt. Mit Datensätze eintragen mittels php - erweiterte Form (mit Sicherheitsabfragen) Um wirklich sicher zu sein, daß nur eingegebene Werte in die Datenbank übernommen werden, müssen wir also unsere Variablen wieder auf Null zurücksetzen. Leider kann man dies nur erreichen, wenn man die Seite neu aufruft, denn selbst ein unset($_POST); nimmt zwar den Variablen ihren Wert, aber bei einer Aktualisierung verfährt der Browser natürlich trotzdem wie zuvor und übergibt sie erneut. Die Lösung dafür liegt in einer weiteren if-Abfrage und besagtem Neuaufruf der Seite im Header der Datei. Also erweitern wir unseren Code um besagte Kopfzeilen und fügen auch noch gleich eine Abfrage ein, ob überhaupt eine Eingabe getätigt wurde. Unser Code sieht dann wie folgt aus: |
|
|
|
Wie man sieht, haben wir im Kopf diesselbe Abfrage wie sie schon im unteren Teil Verwendung fand, nämlich ob unser submit-Button gedrückt wurde. Der Befehl header("refresh: 3; url=http://localhost/index.php"); bewirkt, daß nach 3 Sekunden (refresh: 3) die unter url angebene Adresse aufgerufen wird. Da die Adresse das eigene Dokument ist, wird die Seite einfach komplett neu geladen. Trotz unserem "Reload" der Seite wird der Rest der Seite ausgeführt. Somit kann man noch auf die Datenübergabe hinweisen und daß die Page nach 3 Sekunden neu geladen wird. Oder man ändert die Kopfzeile in header("Location: http://localhost/index.php"); und lädt die Seite ohne Verzögerung neu. |
|
Inhalt der Datenbank anzeigen lassen Nun da wir unsere Datenbank mit Werten gefüllt haben, wollen wir diese auch wieder anzeigen lassen. Dabei hilft uns folgendes Listing: |
|
|
|
Den Anfang macht natürlich wie bei jedem Datenbankzugriff unsere Verbindungsdaten die wir mittels include einbinden. Anschließend wird die Abfrage generiert und in die Variable $anzeige geschrieben. Dabei bedeutet SELECT * FROM liste soviel wie "wähle alles (der Stern als Platzhalter für alles) aus der Tabelle liste". Anschließend wird mittels echo eine Tabelle generiert und durch die while-Schleife Spalte für Spalte mit den Datensätzen aus der Datenbank gefüllt. Das Kernelement der while-Schleife bildet hier mysql_fetch_object, welches aus unserer Datenbankabfrage die einzelnen Objekte (in dem Fall die einzelnen Datensätze) ausschneiden kann. Mittels $row->spalte kann man die einzelnen Spalten übergeben. Interessant ist hier der Zeilenvorschub \n, welcher zwar keinen Zeilenvorschub in der Ausgabe des Webdocuments bewirkt (das macht natürlich nur <br>), aber einen Zeilenvorschub im Code bewirkt. Dadurch wird der Code bei einer späteren Einsicht mittels des Webbrowsers ein wenig übersichtlicher, da nicht alles in eine Zeile gequetscht wird. Inhalt der Datenbank anzeigen - Ausgabe Seitenweise Jetzt wirds ein wenig komplizierter, denn eine große Datenbank mit vielen Einträgen Seitenweise ausgeben und als zusätzliche Schwierigkeit in einem Dokument, dafür braucht man schon ein paar mehr if-Abfragen. Fangen wir mit dem kompletten Listing an: |
|
|
|
Diesmal öffnen wir gleich im Kopf unserer Seite mit der include-Anweisung die Datenbank. Mit dem sql-Befehl SELECT COUNT(*) AS anzahl FROM tabelle erreichen wir eine Zählung aller Einträge in der Datenbank. Diese Zählung müssen wir in ein Array schreiben und können die Zahl anschließend der Variablen $gesamtanzahl übergeben. Anschließend wir die momentane Seite definiert. Im Falle, daß das Dokument das erste Mal geöffnet wurde, ist die Seitenvariable noch nicht definiert und bekommt den Standardwert $seite=1 zugewiesen. Die Seitenvariable wird später durch die Seitenweiterschaltung im Wert erhöht oder erniedrigt. Nach diesem Prinzip -mittels if-Abfragen- werden allen für die Berechnung der Seiten unbedingt benötigten Variablen Standardwerte zugewiesen. Als Nächstes erfolgt die Zuweisung der Einträge pro Seite in der Variablen $zeilenzahl. Nun haben wir beide Werte um die Anzahl der benötigten Seiten zu berechnen. Dazu teilen wir die Anzahl der Einträge pro Seite durch die Anzahl der Einträge in der Datenbank und runden das Ergebnis mittels ceil auf. ceil rundet bei einem Kommawert auf die nächst höhere Ganzzahl auf und ist daher wie geschaffen für die Ermittlung unserer benötigten Seiten. Die folgende if-Abfrage dient nur zur Sicherheit um sicherzustellen, daß der Wert der Seite in einem gültigem Bereich liegt. Bei einer Umschaltung der Einträge pro Seite soll die momentan aktuelle Seite beibehalten werden, jedoch kann es bei der Umschaltung von einem niedrigen auf einen hohen Wert sein, daß die betreffende Seite gar nicht existiert. In dem Fall wird durch die if-Abfrage auf die letzte Seite gewechselt. Mit der vorher festgelegten Seite können wir den Startwert $startpos unserer Einträge pro Seite ermitteln. Das geht ganz einfach indem wir die Seite um -1 herabsetzen und mit der Anzahl der Einträge pro Seite multiplizieren. Anschließend berechnen wir noch den Endwert $endpos für die LIMIT Anweisung in der Datenbankabfrage. Für eine korrekte Berechnung der tatsächlichen Einträge pro Seite (auf der letzten Seite können es ja weniger Einträge sein) ist diese Angabe allerdings nicht zu gebrauchen. Diesen Wert berechnen wir mittels mysql_num_rows, welcher die aus der Datenbank empfangenen Zeilen wiedergibt und in der Variablen $currentcount speichert. Dadurch ist es möglich im Kopf unseres Dokuments eine exakte Angabe "Einträge von ... bis ..." zu machen. Natürlich müssen wir vorher unsere Daten aus der Datenbank abfragen um einen gültigen Wert für $currentcount zu erhalten. Dafür müssen wir aber zuerst noch unsere $alphabet-Variable holen, welche den Wert einer checkbox enthält, mit der wir die Ausgabe der Datenbank nach der ID sortieren können. Ohne Sortierung werden die Einträge in der Reihenfolge ausgegeben wie sie in die Datenbank geschrieben wurden. Mit der alphabet-if-Abfrage werden die Abfragen einmal nach alphabetischer Sortierung generiert und einmal ohne. Dafür fragen wir die Variable für $alphabet erneut ab und erstellen die Abfrage entweder mit ORDER BY spalte oder ohne. Die Limit-Anweisung fordert nur angegebene Einträge aus der Datenbank an, dabei setzt sich die Anweisung wie folgt zusammen: Der HTML-Code auf unserer Seite ist recht unspektakulär. Wir spannen lediglich eine komplette Tabelle mit einer einzigen Zelle um unsere ganzen Elemente. Der Inhalt der Datenbank wird in eine eigene Tabelle innerhalb dieser umschließenden Tabelle geschrieben. Alle weiteren HTML-Elemente werden gleich mit echo-Anweisungen im folgenden php-Code generiert. Man hätte zwar auch den php-Code ständig unterbrechen und neubeginnen können, ob dadurch der Code allerdings übersichtlicher wird ist dem jeweils eigenem Geschmack vorbehalten. Der Freiheit in der Gestaltung sind hier keine Grenzen gesetzt.
Im nun folgenden php-Code können wir zu informativen Zwecken die im Kopf berechneten Variablen ausgeben lassen. Wir beginnen gleich mal mit der Gesamtanzahl der Einträge in unserer Datenbank. Danach folgt das Drop-Down-Menü mit dem wir unsere Einträge pro Seite selbst einstellen können. Dieses Element steckt in einem eigenem Formular, welches unabhängig von den Formularen für die Checkbox oder die Seitenweiterschaltung ist. Da jedes Formular nur die Variablen seiner eigenen Elemente abschickt, kann man die sonstigen benötigten Variablen mittels sogenannter Hidden-Elemente dem Seitenaufruf des Formulars mitgeben. Damit beim Wechsel der Einträge pro Seite die aktuelle Seite und die Sortierung beibehalten wird, müssen wir die Variablen $seite und $alphabet mitschicken. Da unser Drop-Down-Menü nach einer Auswahl und neuladen der Seite immer auf den allerersten Eintrag springt, geben wir einen Hinweis aus für die gewählte Anzahl. Auch ist das der Grund dafür, daß der allererste Eintrag keine Zahl, sondern das Wort wählen ist. Das Wort "wählen" kann zwar ausgewählt werden, wegen der onchange-Anweisung hat es aber keinerlei Auswirkung, da besagte Form eben nur bei einer Änderung ausgeführt wird ("wählen" erneut auszuwählen ist keine Änderung). Ebenfalls ist das der Grund, warum wir das Drop-Down-Menü in ein eigenes Formular packen müssen. Würde es im Formular der Checkbox stehen, würde bei einer Änderung der Checkbox die momentan gewählte Einstellung als Variable übergeben, was dann das Wort "wählen" wäre und damit ein invalider Wert für die Anzahl der Einträge pro Seite. Dies würde zu einem massivem Fehler in der Webseite führen. Interessant ist, daß unser Drop-Down-Menü von Haus aus kein Ausführen des Formulars und damit Neuladen der Seite bei der Änderung eines Wertes initiiert. Dafür müssen wir die Action onchange und einen Javascript Befehl namens this.form.submit() bemühen. Mittels der while-Schleife werden die Einträge Zeile für Zeile ausgelesen. Falls nicht in allen Zellen der Datenbank Werte stehen, wird durch die if-Abfrage stattdessen ein (nonbreakablespace=Leerzeichen) eingefügt um die Optik der Tabelle nicht zu gefährden. Ein Rahmen wird nur gezogen, wenn die Zelle in der Tabelle auch einen Inhalt aufweist. Damit ist unsere Seitenweise Ausgabe einer Datenbank fertig. Zur Ergänzung für die Datenbankausgabe noch ein paar weitere Abfrage-Beispiele: |
|
|
|
Mit Hilfe von COUNT kann man die Gesamtanzahl der Einträge in einer Tabelle ausgeben. Möchte man die Gesamtanzahl einzelner Einträge hilft | |
|
|
Wie man sieht, erweitert sich der Abfrage-Befehl um die Komponenten GROUP BY und ORDER BY, wobei Ersteres die Spalte auswählt, die zusammengefaßt werden soll. In dem Fall unsere Spalte "hersteller", also werden sämtliche gleichen Hersteller zusammengezählt. Die Komponente ORDER BY gibt an, nach welcher Ausgabe sortiert werden soll. In unserem Fall nach der Anzahl in absteigender (DESC) Reihenfolge, also tauchen die am häufigsten vorkommenden Hersteller in der Liste ganz oben auf, gefolgt von den weniger häufigeren. Mittels der while-Schleife gibt man die zusammengezählten Einträge aus. Und noch mehr mögliche Abfragen: |
|
|
|
Standardmäßig verwendet mysql die LIMIT-Anweisung 0,30, d.h. es werden nur die ersten 30 Zeilen ausgegeben.
Damit haben wir die Grundfunktionen: Daten in die Datenbank eintragen und wieder auslesen. Am Anfang des Beitrags haben wir die Datenbank mit phpmyadmin erstellt. Der Vollständigkeit halber kommen jetzt noch die entsprechenden php-Befehle zum Erstellen oder Löschen der Datenbank oder einer Tabelle und zum Ändern von Datensätzen. Datenbank oder Tabelle anlegen |
|
|
|
Der Befehl zum Anlegen einer Tabelle lautet CREATE TABLE tabellenname (Spaltename1 Datentyp Sonstiges, Spaltenname2 Datentyp Sonstiges, ...) ENGINE=verwendete Engine; Eine bereits existierende Tabelle wird dabei nicht überschrieben, sondern führt zu einer Fehlermeldung, welche man sich mit echo mysql_error(); ausgeben lassen kann. Möchte man die Fehlermeldung unterdrücken läßt man entweder die echo Anweisung weg oder fügt einen Zusatz an den Befehl an: CREATE TABLE IF NOT EXISTS. |
|
|
|
Der Befehl zum Anlegen einer Datenbank ist simpel: CREATE DATABASE Datenbankname. Genau wie bei CREATE TABLE wird eine existierende Datenbank nicht angerührt und führt zu einer Fehlermeldung. Datenbank oder Tabelle löschen Um eine komplette Datenbank oder eine einzelne Tabelle zu löschen gibt es folgende Befehle: |
|
|
|
Die Befehle zum löschen werden ohne Rückfrage ausgeführt! Möchte man eine Sicherheitsabfrage, so ist diese mittels php selbst zu definieren! Einträge in der Datenbank überschreiben/ändern |
|
|
|
Mittels UPDATE werden bestehende Datensätze überschrieben. Dabei kann man die einzelnen Spalten mit dem Wert durch Komma getrennt hintereinander angeben. Die WHERE-Anweisung sagt, welcher Datensatz geändert werden soll. Läßt man WHERE weg, würden sämtliche Datensätze in der Tabelle mit den neuen Werten überschrieben werden. Noch ein Beispiel: |
|
Zurück zur Auswahl | |