PHP Tutorial: Datenbankprogrammierung mit PHP und MySQL

PHP Tutorial: Datenbankprogrammierung mit PHP und MySQL

Die Programmiersprache PHP bietet bezüglich der Sprachmerkmale beste Voraussetzungen zur Kommunikation mit einer Datenbank. MySQL ist kostenfrei und läuft auf vielen Betriebssystemen. Die ideale Kombination also! Ebenso ist es recht einfach, mit PHP auch andere Datenbanken anzusprechen.

Webbasierte Anwendungen erfordern in der Regel auch eine umfassende Datenverwaltung. Das relationale Datenbankschema ist seit vielen Jahren Standard und nach wie vor für die meisten Anwendungszwecke bestens geeignet.

Im Zusammenhang mit PHP wird sehr häufig mit MySQL-Datenbanken gearbeitet. MySQL ist eine Open-Source-Datenbank, die seit Jahren zur Verfügung steht und einen hohen Verbreitungsgrad hat, wozu gute Dokumentationen, Hilfen im Web und vielfältige Werkzeuge beitragen. In zahllosen Projekten hat sich die Zusammenarbeit von PHP und MySQL über Jahre bewährt. Das ist für uns Grund genug, sich intensiv damit auseinanderzusetzen (Kasten „Artikelserie“).

Wie gehen wir vor? Zunächst wird gezeigt, wie wir eine einfache Datenbank in MySQL anlegen und administrieren. Dazu sind Basiskenntnisse in der Datenbanktheorie notwendig. Im Textkasten „Basics der Datenbanktheorie“ werden die wichtigsten Begriffe zum relationalen Datenschema erklärt.

Im zweiten Schritt geht es darum, eine Verbindung zwischen dem PHP-Programm und der Datenbank herzustellen. Die Daten werden üblicherweise in einem Formular erfasst, nach der Validierung an die Datenbank übertragen und dort gespeichert. Die in der Datenbank abgelegten Daten muss man natürlich auch wieder abrufen können, um sie anzuzeigen oder weiterzuverarbeiten.

Alle Arbeiten mit der Datenbank erfolgen mithilfe von Transaktionen. Dazu dient die allgemeine Datenbanksprache SQL, auf die wir im Lauf des Artikels noch zurückkommen werden. Damit ist die Agenda für diesen Teil unserer einführenden PHP-Serie abgesteckt. Das Vorhaben ist wie immer anspruchsvoll, lassen Sie uns darum direkt starten!

Basics der Datenbanktheorie

Eine Webapplikation mit Datenbankzugriffen zu programmieren, ohne sich mit der zugrunde liegenden Datenbanktheorie zumindest rudimentär auszukennen, ist nicht möglich. Daher folgen hier ein paar Grundlagen.

Ein Datenbanksystem ist ein System zur effizienten, dauerhaften und widerspruchsfreien Speicherung von Daten. Da neben der Datenspeicherung auch Verwaltungsaufgaben wahrgenommen werden müssen, spricht man auch von einem Datenbankmanagementsystem (DBMS). Innerhalb eines solchen DBMS können prinzipiell beliebig viele Datenbanken (DB) verwaltet werden. Insgesamt ergibt sich dann die in Abbildung 1 dargestellte Struktur. Weiterhin basieren die meisten DBMS auf dem relationalen Datenbankschema, mit dem Daten innerhalb von Tabellen organisiert werden. Eine solche Tabelle besteht aus Zeilen und Spalten; jede Spalte hat dabei einen bestimmten Datentyp und steht für eine ausgewählte Komponente eines Datensatzes, jede Zeile beinhaltet genau einen Datensatz.

Um jeden Datensatz eindeutig identifizieren zu können, muss man diesen mit einem eindeutigen Schlüssel ausstatten. Üblicherweise wird ein künstlicher Schlüssel in jede Tabelle eingefügt, dessen Wert automatisiert beim Hinzufügen eines neuen Datensatzes generiert wird. Ein solcher Schlüssel kann zum Beispiel eine fortlaufende Nummer sein. Auch inhaltliche Informationen (z. B. eine Kundennummer) kann man in dem Schlüssel „verstecken“. Alternativ kann ein Schlüssel auch aus einem oder mehreren Feldern (Kombination) gebildet werden. Voraussetzung ist jedoch, dass der Schlüssel in Bezug auf den Datensatz eindeutig ist.

Das Prinzip der relationalen Datenbank besteht darin, die zu speichernden Informationen auf mehrere Tabellen aufzuteilen. Dabei sind die Informationen so in den Tabellen abzulegen, dass möglichst keine Redundanzen entstehen, d. h. eine Information sollte nach Möglichkeit nur einmal abgelegt werden.

Der Vorteil davon ist, dass man bei Änderung eines bestimmten Datums dieses nur an einer Stelle anpassen muss. Damit werden Fehler und Widersprüche im Datenbestand vermieden bzw. reduziert. Erreicht wird das durch eine Normalisierung der Datenbasis. Dieser Schritt im Datenbankentwurf wird als konzeptioneller Entwurf bezeichnet. Wenn Sie als angehender PHP-Entwickler mit Datenbanken grundsätzlich vertraut sind, werden Sie sofort wissen, was damit gemeint ist. Alle anderen müssen sich damit beschäftigen, bevor sie eine Datenbank für eine dynamische Webapplikation erstellen.

Abb. 1: Prinzip der Zusammenarbeit von Programm (Client) und Datenbank (DBMS-Server) [1]

Abb. 1: Prinzip der Zusammenarbeit von Programm (Client) und Datenbank (DBMS-Server)

Datenbank erstellen

In diesem Schritt zeigen wir, wie man die grundlegende Struktur einer Datenbank anlegt. Unser Beispiel wird sehr minimalistisch ausfallen, d. h. die Datenbank wird nur aus einer Tabelle mit drei Spalten bestehen. Dennoch werden wir alle wichtigen Schritte daran zeigen. Zunächst ist MySQL zu starten. Wir gehen wieder davon aus, dass Sie den Server XAMPP verwenden (siehe Teil 1 unserer Serie). Starten Sie den Server und damit auch gleichzeitig die MySQL-Datenbank, indem Sie die Datei xampp_start.exeaus dem Explorer heraus ausführen. Den Erfolg dieser Maßnahme können Sie über das Control-Panel (xampp-control.exe) kontrollieren (Abb. 2). Für das Anlegen der Struktur der Datenbank gibt es zwei Varianten:

Abb. 2: Im XAMPP-Control-Panel kann man den Status vom PHP- und MySQL-Server sehen

Abb. 2: Im XAMPP-Control-Panel kann man den Status vom PHP- und MySQL-Server sehen

  1. Automatisiert: Aus dem Quellcode des Programms wird mittels PHP und den entsprechenden SQL-Befehlen die Datenbank erstellt. Das passiert immer dann, wenn die Tabellenstruktur der Datenbank bereits feststeht und automatisiert, zum Beispiel im Rahmen einer Programminstallation, auf dem Server erstellt werden soll.
  2. Manuell: Man erstellt die Struktur der Datenbank manuell. Meist bedient man sich dazu einer Bedienoberfläche. In der PHP-Welt und für den Zugriff auf MySQL-Datenbanken funktioniert das sehr gut mithilfe des kostenfreien Tools phpMyAdmin.

Wie wollen hier keine Ausnahme machen und eine erste Datenbank mithilfe von phpMyAdmin erstellen. Das Tool selbst ist auch ein PHP-Programm und läuft daher im Browser. Wechseln wir darum also in den Browser und rufen unseren lokalen Server (http://localhost) auf; phpMyAdmin erreichen wir unter http://localhost/phpmyadmin/ (Abb. 3).

Abb. 3: Einfachste Administration der MySQL-Datenbank mithilfe von phpMyAdmin

Abb. 3: Einfachste Administration der MySQL-Datenbank mithilfe von phpMyAdmin

Damit gelangen wir zur Administrationsoberfläche und können bestehende Datenbanken verwalten oder eine neue Datenbank anlegen. Wir klicken auf Neu, um eine neue Datenbank zu erstellen, für die ein aussagekräftiger Name zu vergeben ist: Für den ersten Test nennen wir sie „meineDatenbank“. Die Datenbank wird erstellt und wir gelangen zur nächsten Seite, auf der wir aufgefordert werden, eine erste Tabelle zu erstellen. Dabei muss unmittelbar die Anzahl der Spalten – also die Zahl der Datenfelder – angeben werden. Im nächsten Schritt sind für jedes Datenfeld der Datentyp (Tabelle 1) und weitere Eigenschaften zu bestimmen.

DatentypSpeichergrößeWertebereich
TINYINT1 ByteGanzzahlen: 0 bis 255Mit Vorzeichen: -128 bis +127
SMALLINT2 BytesGanzzahlen: 0 bis 65 535Mit Vorzeichen: -32 768 bis +32 767
MEDIUMINT3 BytesGanzzahlen: 0 bis 16 777 215Mit Vorzeichen: -8 388 608 bis +8 388 607
INT4 BytesGanzzahlen: 0 bis 4 294 967 295Mit Vorzeichen: -2 147 483 648 bis +2 147 483 647
BIGINT8 BytesGanzzahlen: 0 bis 18 446 744 073 709 551 615Mit Vorzeichen: -9 223 372 036 854 775 808 bis +9 223 372 036 854 775 807
FLOAT4 BytesFließkommazahlenGanzzahlen: 0 und 1,175494351^38 bis 3,402823466^38

Mit Vorzeichen: -3,402823466^38 bis +1,175494351^38

DOUBLE8 BytesFließkommazahlenGanzzahlen: 0 und 2,225^-308 bis 1,798^308

Mit Vorzeichen: -1,798^308 bis +2,225^-308

DATE3 BytesDatumsbereich: von 01.01.1000 bis 31.12.9999
DATETIME8 BytesDatumsbereich: von 01.01.1000 – 00:00:00 bis 31.12.9999 – 23:59:59
TIMESTAMP4 BytesWertebereich: von 01.01.1970 bis 2037
VARCHARStringlänge + 1 ByteZeichenkette mit einer Länge von 0 bis 255 Zeichen
TEXTStringlänge + 2 BytesZeichenkette mit einer maximalen Größe von 65 535 Bytes
MEDIUMTEXTStringlänge + 3 BytesZeichenkette mit einer maximalen Größe von 16 777 215 Bytes
LONGTEXTStringlänge + 4 BytesZeichenkette mit einer maximalen Größe von 4 294 967 295 Bytes

Tabelle 1: Wichtige Datentypen, Speicherbedarf und Einsatz der Datenbank MySQL

Bei der Auswahl der Datentypen ist aus Performancegründen darauf zu achten, dass der kleinstmögliche Datentyp gewählt wird. Wenn Tabellen miteinander verknüpft werden, sollten die betreffenden Felder vom gleichen Datentyp sein. In Abbildung 4 haben wir das bereits für die Datenfelder id (integer)vorname (varchar) und nachname (varchar) getan. Das Datenfeld id wurde dabei als Primärschlüssel definiert. Auf diese Weise können wir eine beliebige Datenbankstruktur mit mehreren Tabellen erstellen. Wichtig ist es dabei, sich im Vorfeld über die Struktur im Klaren zu sein. Sind erst Produktionsdaten in der Datenbank abgelegt, wird es sehr aufwändig, die Struktur nachträglich ohne Informationsverlust anzupassen. Auch das Transferieren der Daten in eine neue Struktur ist dann kompliziert.

Abb. 4: Anlegen der Datenbankstruktur mithilfe von phpMyAdmin

Abb. 4: Anlegen der Datenbankstruktur mithilfe von phpMyAdmin

Ebenso ist es möglich, die Tabellenstruktur der Datenbank über PHP zu erstellen. Für unsere minimale Datenbank geschieht das mithilfe von Listing 1. Dabei ist zu beachten, dass wir als Benutzer root arbeiten und zu Beginn kein Passwort definiert wurde. Diesen Zustand haben wir zum Testen so belassen. Sobald man mit einem ersten richtigen Projekt beginnt, sind die Sicherheitseinstellungen anzupassen, d. h. man muss ein Passwort für root vergeben. Zusätzlich sollte man auch einen weiteren Nutzer anlegen und diesen nur mit den minimal notwendigen Rechten ausstatten. Das kann ebenfalls innerhalb von phpMyAdmin erfolgen.

Listing 1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!DOCTYPE html>
<html>
<head>
  <Title>Ein neuer Versuch</Title>
</head>
<body>
  <?PHP
    $user = 'root';
    $pass = '';
    $db = new PDO('mysql:host=localhost;dbname=meineDatenbank', $user, $pass );
    //Fehlermeldungen aktivieren
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    //Datenbank erstellen
    $sql = "CREATE TABLE tabelle(id INTEGER PRIMARY KEY NOT NULL auto_increment,vorname VARCHAR(100), nachname VARCHAR(100), age int);";
    $db ->exec($sql);
    echo 'Die Tabelle "tabelle" wurde erfolgreich erstellt!'
  ?>
</body>
</html>

Startet man das Skript aus Listing 1 und existiert eine Datenbank mit dem Namen „meineDatenbank“, so wird die Datentabelle erstellt. Den Erfolg dieser Maßnahme bekommt man im Browser angezeigt. Unsere Datenbank besteht damit aus den Feldern id, vorname, nachname und age.

👉 Hinweis: Statt des deutschen Worts alter müssen wir auf die englische Bezeichnung age ausweichen, da alter innerhalb von SQL ein Schlüsselwort ist!

Nach dem Ausführen des Skripts ist die Tabellenstruktur wie gewünscht angelegt und damit bereit, erste Datensätze aufzunehmen.

In Verbindung treten

Bei der Erstellung der Tabelle aus PHP heraus (Listing 1) haben wir bereits eine Datenbankverbindung aufgebaut, ohne dass wir das näher erläutert haben. Gemeint sind die beiden Befehlszeilen:

1
2
$db = new PDO('mysql:host=localhost;dbname=meineDatenbank', $user, $pass );
$db->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );

Grundsätzlich gibt es mehrere Möglichkeiten, von PHP auf eine Datenbank zuzugreifen. Bei Verwendung einer MySQL-Datenbank wählt man üblicherweise die Schnittstelle MySQLi, die auf der ursprünglichen MySQL-Schnittstelle basiert. Das „i“ steht für improved, d. h. für verbessert. Mithilfe von MySQLi stellt sich das Vorhaben gemäß Listing 2 dar.

Listing 2: Prinzip des Datenzugriffs aus PHP mit MySQLi [3]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
  /* Verbindung aufnehmen */
  $con = mysqli_connect("","root");
  /* Datenbank auswählen */
  mysqli_select_db($con, "namederdatenbank");
  /* SQL-Abfrage ausführen */
  $res = mysqli_query($con, "select * from tabellenname");
  /* Anzahl Datensätze ermitteln und ausgeben */
  $num = mysqli_num_rows($res);
  echo "$num Datensätze gefunden<br />";
  /* Datensätze aus Ergebnis ermitteln, */
  /* in Array speichern und ausgeben    */
  while ($dsatz = mysqli_fetch_assoc($res))
  {
    echo $dsatz[“feldname”]
    ...
  }
  /* Verbindung schließen */
  mysqli_close($con);
?>

Dazu sind die folgenden Erläuterungen angebracht:

  • mysqli_connect(): Öffnet eine Verbindung zum MySQL-Datenbankserver. Als Parameter werden der Hostname, der Benutzername und das Kennwort übergeben.
  • mysqli_select_db: Wählt die betreffende Datenbank aus. Als Parameter werden der Verweis auf die Verbindung und der Name der Datenbank übergeben.
  • mysqli_query(): Führt die Abfrage mithilfe einer select-Abfrage an die Datenbank durch. Das Ergebnis der Abfrage wird zurückgegeben.
  • mysqli_num_rows(): Ermittelt die Anzahl der Datensätze. Als Parameter muss man das Ergebnis eines vorher erforderlichen mysqli_query()-Statements übergeben.
  • mysqli_fetch_assoc(): Damit wird ein Datensatz aus dem Ergebnis ermittelt. Bei jedem Aufruf wird der Datensatzzeiger um eine Position verschoben. Mithilfe einer while-Schleife kann man also über alle Datensätze iterieren.
  • mysqli_close(): Die Verbindung zur Datenbank wird wieder geschlossen.

Steht also fest, dass mit dem PHP-Programm auch in der Zukunft eine MySQL-Datenbank angesprochen wird, brauchen Sie sich über weitere Schnittstellen keine Gedanken zu machen. Sofern man aber einen Wechsel der Datenbank nicht grundsätzlich ausschließen kann, hat die Festlegung einer spezifizierten Schnittstelle einige Nachteile. Wird auf ein anderes Datenbanksystem gewechselt, müssen die betreffenden Stellen im Quellcode angepasst werden, die für den Datenbankzugriff verantwortlich sind.

Um das zu vermeiden, setzt man Abstraktionsklassen ein, die dafür sorgen, dass die Programmierung des Datenbankzugriffs grundsätzlich unabhängig von der letztendlich eingesetzten Datenbank erfolgt. Ehrlicherweise muss jedoch hinzugefügt werden, dass es auch beim Einsatz einer Abstraktionsklasse notwendig sein kann, dass man beim Wechsel des Datenbanksystems Anpassungen am Quellcode vornehmen muss.

source:-entwickle