Datenbankzugriff Internet-Anwendungen mit Datenbankzugriff sind s.g. 4-TierArchitekturen: Clientebene Tier 1 Präsentationsebene www.webpage.com (HTML) Text Ebene des Webservers Tier 2 Verteilungsebene Ebene der Anwendungslogik (serverseitige Skripte) Tier 3 Webserver serverseitiges Script-Programm Datenbankebene Tier 4 Persistenzebene Danbankmanagementsystem (DBMS) Internet Information Server oder Apache Peter Sobe Active Server Pages oder PHP Internettechnologien MS access, SQL Server oder MySQL 86 PHP-Datenbankzugriff (1) Verbinden mit einem Datenbanksystem: Als erster Schritt muss immer mit einem Datenbanksystem Verbindung aufgenommen werden. Das Datenbanksystem (hier MySQL) kann auf dem gleichen Rechner wie der Webserver laufen, oft aber auch auf einem separaten Rechner, für den eine IP-Adresse anzugeben ist. Beispiel: $host=“localhost“; // in diesem Fall ein lokales Datenbanksystem $user=“httpd“; $passwort = ““; $verbindung = mysq_connect($host, $user,$passwort); if ($verbindung) { echo “<p>mit Datenbanksystem verbunden </p>\n“;} else {echo “<p>Fehler beim Verbinden mit Datenbanksystem </p>\n“;} Peter Sobe Internettechnologien 87 PHP-Datenbankzugriff (2) Verbinden mit einem Datenbanksystem: Die Funktion mysql_connect stellt die Verbindung mit einem MySQL-Datenbanksystem her. int mysql_connect([ string hostname [:port] [, string username [, string passwort ]]]); Bei erfolgreichem Verbinden wird ein Link-Identifier zurückgegeben, der in den meisten Funktionen zur Arbeit mit der Datenbank angegeben werden muss. Trennen von einem Datenbanksystem: int mysql_close([int link_identifier]); Informationen zu Fehlern ausgeben: int mysql_errno ([int link_identifier]); Hinweis: Parameter in [ ]-Klammern sind optional, d.h. sie können unter Umständen auch weggelassen werden. Peter Sobe Internettechnologien 88 PHP-Datenbankzugriff (3) Ein Datenbanksystem kann eine Reihe verschiedener Datenbanken verwalten. Jede Datenbank organisiert die Daten selbst möglicherweise in mehreren Tabellen. Auswählen einer Datenbank: $dbname=“opticalproducts“; if (mysql_select_db($dbname, $verbindung )) { echo “<p>Datenbank erfolgreich ausgewählt</p>\n“;} else {echo “<p>Fehler beim Auswählen der Datenbank </p>\n“;} … Syntax und Interface: int mysql_select_db(string database_name [, int link_identifier]); Peter Sobe Internettechnologien 89 PHP-Datenbankzugriff (4) Wenn für eine Verbindung eine Datenbank ausgewählt wurde, können Zugriffe auf die Datenbank erfolgen. Beispiel: Zeilen (rows) abrufen und als HTML ausgeben $sql = “SELECT * FROM opticalproducts“; $ergebnis = mysql_query($sql, $verbindung); if ($ergebnis) { echo “<table>“; while ($zeile = mysql_fetch_row($ergebnis)) { echo “<tr>“; for ($i=0; $i<mysql_num_fields($ergebnis);$i++) echo “<td>. $zeile[$i].</td>“; echo “</tr>“; } echo </table> mysql_free_result($ergebnis); } else { echo “Fehler bei Abfrage“; } Peter Sobe Internettechnologien 90 PHP-Datenbankzugriff (5) Datenbankzugriffsfunktionen: int mysql_query(string SQL_anfrage [, int link_identifier]); Die Anfrage wird als String in der SQL-Syntax übergeben (SQL: Structured Query Language) Die Funktion liefert einen Verweis auf ein Ergebnis oder Null, wenn Anfrage nicht erfolgreich war. Das Ergebnis besteht aus keiner, einer, oder mehreren Zeilen, die schrittweise abgefragt werden können. int mysql_num_rows(int ergebnis); … gibt die Anzahl der Zeilen im Ergebnis zurück. array mysql_fetchrow(int ergebnis); … wählt die jeweils nächste Zeile im Abfrageergebnis aus. Als Rückgabe wird ein Array erzeugt, das die einzelnen Werte der Zeile enthält. Peter Sobe Internettechnologien 91 PHP-Datenbankzugriff (6) Datenbankzugriffsfunktionen (Fortsetzung): mysql_free_result(int ergebnis); … schließt die Ergebnismenge und gibt die Ressourcen frei mysql_fetch_row() gibt immer die nächste Zeile zurück. Es ist aber auch möglich, eine spezielle Zeile auszuwählen: mysql_data_seek(int ergebnis, int row_number); Nach mysql_data_seek() gibt der nächste mysql_fetch_row()Aufruf die durch row_number bezeichnete Zeile des Abfrageergebnisses aus. Peter Sobe Internettechnologien 92 PHP-Datenbankzugriff (7) Varianten des Zugriffs auf Abfrageergebnisse: Bislang bekannt: array mysql_fetchrow(int ergebnis) … liefert ein numerisches Array a zurück, das über die Indizes 0 bis mysql_num_fields($a)-1 angesprochen werden kann array mysql_fetch_array(int ergebnis [, int erg_type]) liefert als Standard ein assoziatives Array zurück. Die Funktion kann durch erg_type=MYSQL_ASSOC oder erg_type=MYSQL_NUM zwischen der Ausgabe eines assoziativen oder numerischen Arrays umschalten. Beispiel umseitig … Peter Sobe Internettechnologien 93 PHP-Datenbankzugriff (8) Beispiel zu mysql_fetch_array(int ergebnis [, int erg_type]) … $ergebnis = mysql_query(“SELECT * FROM pruefungsergs“); while($zeile = mysql_fetch_array($ergebnis ,MYSQL_ASSOC)) { while(list($index,$wert) = each($zeile)) echo “$index : $wert “; echo “<br/>“; } Matrnr Name Vorname Note Bei einer 111222 Meier Max 2.3 Tabelle laut … 111225 Schulze Iris 1.7 würde man erhalten: Matrnr : 111222 Name : Meier Vorname : Max Note : 2.3 Matrnr : 111225 Name : Schulze Vorname : Iris Note : 1.7 Peter Sobe Internettechnologien 94 PHP-Datenbankzugriff (9) Eine weitere Variante ist die zeilenweise Ausgabe des Abfrageergebnisses als Objekt: object mysql_fetch_object(int result [, int result_typ]) Beispiel aufbauend auf letzter Tabelle: echo “<table>“; while( $zeile=mysql_fetch_object($ergebnis)) { echo “<tr>“; echo “<td>“. $zeile->Matrnr . “ </td> <td>“. $zeile->Note . “</td>“; echo “</tr> \n“; } echo “</table>“; Ausgabe: 111222 2.3 111225 1.7 Peter Sobe Internettechnologien 95 PHP-Datenbankzugriff (10) Einfügen von Daten: $sql=“INSERT INTO pruefungsergs (Matrnr, Name, Vorname, Note) VALUES=(111228, ‘Lehmann‘, ‘Friedrich‘, 1.0)“; if (mysql_query($sql, $verbindung) ) echo mysql_affected_rows() . “Datensätze eingefügt.“; else echo “Fehler: keine Daten eingefügt“; Das Einfügen erfolgt über eine entsprechende SQL-Anweisung. Typisch sind Formulare, die Daten aus $_POST- Feldelementen in eine Datenbank einfügen. Peter Sobe Internettechnologien 96 Exkurs: Relationale DB und SQL (1) Tabellen = Relationen Zeilen = Tupel Tabellenname Attribut Wetter Ortsnr Ortsname Temperatur Luftdruck 1 Dresden 22 1012 2 Leipzig 20 1010 3 Berlin 25 998 … … … … Peter Sobe Wert mit einem speziellen Datentyp, der je Attribut definiert ist Tupel, auch Datensatz oder Zeile 97 Exkurs: Relationale DB und SQL (2) Datenbanken bestehen typischerweise aus mehreren Tabellen = mehrere Relationen → Mengenorientierte Operationen – Relationenalgebra Die Ausgabe ist immer wieder eine Relation, d.h. eine Tabelle Peter Sobe Internettechnologien 98 Exkurs: Relationale DB und SQL (3) Verkauf Produkte Verk. Nr. ProduktID Anzahl Kunde-ID 1 T 4 42 2 A 2 42 3 K 1 20 4 A 3 20 5 G 1 17 6 T 8 17 Kunden 7 B 4 20 Kunde-ID Name Adresse … … … … 17 Peter 33200 Feldstadt Am Markt 5 20 Kurt 33221 Bachhagen, Hauptstr. 23 42 Heidi 33333 Wiesenhain, Am Waldrand 1 Entwurf durch Menschen mit Kenntnis des Diskursbereichs, Vorzugsweise regelbasierter Entwurf Peter Sobe Produkt-ID Name Preis T Tomate 0.20 A Apfelsaft 1.40 K Katzenfutter 2.30 G Gurke 0.55 B Bier 0.78 99 Exkurs: Relationale DB und SQL (4) Mengenorientierte Operationen: Projektion – Auswahl spezieller Spalten Selektion – Auswahl von Zeilen nach Bedingungen Verbund (Join) – Kombination zweier Tabellen zu einer durch ein Verbundprädikat Differenz – Entfernen von Zeilen einer Tabelle, die auch in einer zweiten enthalten sind Durchschnitt – Ausgabe nur von den Zeilen, die in zwei Ausgangstabellen enthalten sind Peter Sobe Internettechnologien 100 Exkurs: Relationale DB und SQL (5) SQL-Anfrage-Grundstruktur SELECT merkmale FROM tabelle [WHERE bedingung] Projektion – Auswahl spezieller Spalten SELECT Name, Preis FROM Produkte Selektion – Auswahl von Zeilen nach Bedingungen SELECT * FROM Produkte WHERE Preis>1.00 Peter Sobe Internettechnologien ProduktID Name Preis T Tomate 0.20 A Apfelsaft 1.40 K Katzenfutter 2.30 G Gurke 0.55 B Bier 0.78 ProduktID Name Preis T Tomate 0.20 A Apfelsaft 1.40 K Katzenfutter 2.30 G Gurke 0.55 B Bier 0.78 101 Exkurs: Relationale DB und SQL (6) SQL-Anfragen Verbund (Join) – Kombination zweier Tabellen zu einer durch ein Verbundprädikat SELECT * FROM Verkauf AS v JOIN Produkte AS p WHERE v.Produkt-ID = p. Produkt-ID Verkauf Produkte Verk.Nr. Produkt-ID Anzahl Kunde-ID Name Preis 1 T 4 42 Tomate 0.20 2 A 2 42 Apfelsaft 1.40 3 K 1 20 Katzenfutter 2.30 4 A 3 20 Apfelsaft 1.40 5 G 1 17 Gurke 0.55 6 T 8 17 Tomate 0.20 7 B 4 20 Bier 0.78 Peter Sobe Internettechnologien 102 PHP- Umgang mit Datenbanken (1) Weitere Funktionen zum Umgang mit Datenbanken (Erzeugen, Löschen) und Tabellen (Erzeugen, Löschen) … Zum Beispiel für das Erzeugen einer neuen Datenbank $dbname=“blumendb“; if (mysql_create_db($dbname, $verbindung)) { … } oder auch über eine SQL-Anweisung: $sql = “CREATE DATABASE $dbname“; if (mysql_query($sql, $verbindung)) { …. } Löschen per mysql_dropdb() oder per SQL-Anweisung “DROP DATABASE $dbname“ Peter Sobe Internettechnologien 103 PHP-Umgang mit Datenbanken (2) Erzeugen einer neuen Tabelle nur per SQL-Anweisung: $tablename=“blumentab“; $sql = “CREATE TABLE $tablename (nummer INT, name VARCHAR (50), gattung_nr INT)“; if (mysql_query($sql, $verbindung)) { …. } Beim Erzeugen muss das Tabellenformat vorgegeben werden. Das Löschen einer Tabelle kann nur über eine SQL-Anweisung erfolgen (keine PHP-Funktion): $tablename=“blumentab“; $sql = “DROP TABLE $tablename“; if (mysql_query($sql, $verbindung)) { …. } Peter Sobe Internettechnologien 104 ODBC (1) Open Data Base Connectivity Der Zugriff auf eine relationale Datenbank erfolgt auf einer WindowsPlattform in der Regel über die Standardschnittstelle Open Data Base Connectivity (ODBC). Mit Hilfe von ODBC kann der Zugriff eines Client auf einen DatenbankServer erfolgen, wenn der Zugriff in der Sprache SQL kodiert ist. Dabei kann auch der Server zu verschiedenen DBMS-Produkten gehören. In der ODBC-Schnittstelle werden die konkreten Verbindungsinformationen abgelegt. Diese werden in eine dsn-Datei geschrieben (dsn – Data Source Name). Dazu gehören vor allem die Treiber für das jeweilige DBMS. Aber auch der Name und die Pfadangaben der Datenbank werden dazu mit benötigt. Peter Sobe Internettechnologien 105 ODBC (2) Prinzipielle Architektur einer ODBC-Schnittstelle ODBC-Schnittstelle Applikation ODBC ODBC Applikation (Client) Manager Treiber (Server) Im Prinzip kann so auf jede DB zugegriffen werden, für die ein ODBC Treiber verfügbar ist. Peter Sobe Internettechnologien 106 ODBC (3) Einrichten einer ODBC-Schnittstelle: Auf einer Windows-Plattform erreicht man den ODBC- DatenquellenAdministrator (Manager) über das Menü Systemsteuerung -> Verwaltung. Durch einen Doppelklick auf Datenquellen (ODBC) wird der ODBCDatenquellen-Administrator geöffnet. Im Fenster ist das Register System-DSN auszuwählen und die Schaltfläche „Hinzufügen“ zu betätigen. Eine System-DSN ist immer zu wählen, wenn ein Zugriff über ein Rechnernetz erfolgt. Befindet sich Client und Server auf einem Rechner, ist das Register Benutzer-DSN auszuwählen. Im Fenster „Neue Datenquelle erstellen“ ist der entsprechende DB-Treiber (zum Beispiel MS-ACCESS) auswählen und Taste „Fertigstellen“ betätigen. Peter Sobe Internettechnologien 107 ODBC (4) Einrichten einer ODBC-Schnittstelle in Bildern: Auswahl Treiber Benennung der Schnittstelle und Verbindung mit einer Datenbank, hier db_bsp.mdb Peter Sobe Internettechnologien 108 ODBC (5) Einrichten einer ODBC-Schnittstelle in Bildern: Übersicht über Datenquellen Peter Sobe Internettechnologien 109 PHP und ODBC (1) Verbinden mit einer ODBC-Datenquelle per PHP: $dsn = “dat“; $user = “administrator“; Datenquellenname aus Systemsteuerung $pw = ““; $verbindung = odbc_connect($dsn,$user,$pw); $sql = “SELECT * FROM orte“; $ergebnis = odbc_exec($verbindung, $sql); odbc_result_all($ergebnis); odbc_result_all() holt das odbc_free_result($ergebnis); gesamte Ergebnis der odbc_close($verbindung); Peter Sobe Internettechnologien Abfrage und gibt es formatiert als HTMLTabelle aus 110 PHP und ODBC (2) Schrittweises Auslesen einer ODBC-Datenquelle per PHP: … In $ergebnis wird ein $verbindung = odbc_connect($dsn,$user,$pw); Verweis auf alle $sql = “SELECT * FROM orte“; Ergebnisse, sowie $ergebnis = odbc_exec($verbindung, $sql); ein Zeiger auf die echo “<table>“ jeweils nächste Ergebniszeile while( odbc_fetch_into($ergebnis, $daten) ) gespeichert { echo “<tr>“; for ($i=0;$i<count($daten);$i++) odbc_fetch_into() holt echo “<td>“.$daten[$i].“</td>“; eine Ergebniszeile und echo “</tr>\n“; speichert sie als Array. } Beim folgenden Aufruf echo “</table>“; wird jeweils die nächste odbc_free_result($ergebnis); Ergebniszeile geholt Peter Sobe Internettechnologien 111 PHP und ODBC (3) Weitere nützliche Funktionen für den ODBC-PHP Zugriff int odbc_fetch_row(int result_id, int [row_number]) … holt die jeweils nächste Ergebniszeile , oder eine spezielle Zeile int odbc_num_fields(int result_id) … gibt Anzahl der Spalten zurück string odbc_field_name(int result_id, int field_number) … gibt die Feldbezeichnung des durch field_number indizierten Elements zurück string odbc_result(int result_id, mixed field) … gibt den Wert eines bestimmten Elements zurück, das entweder durch die Spaltennummer oder die Bezeichnung der Spalte ausgewählt wird Peter Sobe Internettechnologien 112 PHP und ODBC (4) ODBC-PHP-Zugriff: Einfügen neuer Daten … erfolgt über eine SQL-Anweisung, die per odbc_exec() übergeben wird. Beispiel für Einfügen aus einem assoziativen Feld (feld): $dsn=“dat“; $user=“administrator“; $pw = ““; $verbindung=odbc_connect($dsn,$user,$pw); $sql = “INSERT INTO orte VALUES(“; while (list($key,$value) = each(feld)) { if (!value) $feld[$key]= “NULL“) else if ($typ[$key] == “VARCHAR“) $feld[$key] = “ ‘ “.$feld[$key]. “ ‘ “; } $sql = $sql . implode($feld,“, “).“)“; $ergebnis = odbc_exec($verbindung, $sql); … Peter Sobe Internettechnologien Alle value aus den assoziativen Array werden als kommagetrennte Parameter innerhalb VALUES(…) eingebaut. 113