Software- und Organisations-Service GmbH PHP-KLASSEN SOS_Connection Zugriffsschicht für Datenbanken Klassendokumentation 30. November 2005 Software- und Organisations-Service GmbH · Giesebrechtstr. 15 · D-10629 Berlin · Telefon (030) 86 47 90-0 · Telefax (030) 8 61 33 35 Connection - Zugriffsschicht für Datenbanken 2 Inhaltsverzeichnis 1 Zielsetzung ..................................................................................................................................................3 2 Datenbankabstraktion..................................................................................................................................3 2.1 Performance ..........................................................................................................................................3 2.2 Funktionalität .........................................................................................................................................3 2.3 Kompatibilität .........................................................................................................................................4 2.4 Schlussfolgerung für die Abstraktion .....................................................................................................4 3 Unterstützte Datenbanksysteme .................................................................................................................4 4 Methoden.....................................................................................................................................................5 4.1 Standardisierte Aufrufe ..........................................................................................................................5 4.1.1 connect() ........................................................................................................................................5 4.1.2 disconnect()....................................................................................................................................5 4.1.3 get () ...............................................................................................................................................5 4.1.4 get_single ()....................................................................................................................................6 4.1.5 get_single_value () .........................................................................................................................6 4.1.6 get_single_array () .........................................................................................................................6 4.1.7 get_array ().....................................................................................................................................6 4.1.8 get_array_value () ..........................................................................................................................6 4.1.9 execute () .......................................................................................................................................7 4.1.10 update_blob_from_file () ................................................................................................................7 4.1.11 update_blob () ................................................................................................................................7 4.1.12 create_file_from_blob () .................................................................................................................7 4.1.13 commit () ........................................................................................................................................7 4.1.14 rollback () .......................................................................................................................................8 4.1.15 error () ............................................................................................................................................8 4.1.16 get_error () .....................................................................................................................................8 5 SQL-Funktionen ..........................................................................................................................................8 5.1 %lower( $string ) ....................................................................................................................................8 5.2 %upper( $string ) ...................................................................................................................................8 5.3 %now ()..................................................................................................................................................8 5.4 %timestamp ( $timestamp )...................................................................................................................8 6 Fehlermanagement .....................................................................................................................................9 7 Tracing.........................................................................................................................................................9 8 Profiling........................................................................................................................................................9 Software- und Organisations-Service GmbH 30. November 2005 Connection - Zugriffsschicht für Datenbanken 1 3 Zielsetzung Die Klassen des Pakets SOS_Connection implementieren ein einheitliches Interface für den Zugriff auf unterschiedliche Datenbanksysteme. Durch Verwendung dieser Klassen ist es möglich, PHP-Anwendungen für den parallelen Einsatz mit mehreren Datenbanksystemen zu entwickeln. Die Klassen stellen eine Abstraktionsschicht dar, ohne zwanghaft Einschränkungen in der Entwicklung von Anwendungen aufzuerlegen. Als ergänzende Beschreibung steht die API-Dokumentation im PHPDoc-Format zur Verfügung. 2 Datenbankabstraktion Es ist grundsätzlich nicht Ziel einer Abstraktionsschicht unterschiedliche Zugriffsdialekte für Datenbanken auf kleinstem gemeinsamem Nenner zu nivellieren: jede Datenbank hat individuelle Stärken, ein Verzicht auf diese "features" wäre schlicht kontraproduktiv. Entscheidend für die Anwendung ist es eine klare Priorität zwischen der Orientierung an Performance, Funktionalität und Kompatibilität zu finden. 2.1 Performance Datenbanksysteme beherrschen unterschiedliche "features" zur Performance-Optimierung. Ein Beispiel hierfür ist die LIMIT-Klausel von MySQL: select * from sample_table limit 200 durch Verwendung der Klausel kann die Anzahl zurückzuliefernder Datensätze einer Abfrage im vornherein eingeschränkt werden. Die Klausel wirkt nicht erst beim Abholen von Datensätzen aus einer Ergebnismenge, sondern wird bereits in der Datenbankengine zur Optimierung der Suchstrategie verwendet und die Suche bereits abgebrochen wenn die Trefferzahl erreicht ist. Wenn in Web-Seiten beschränkte Ergebnismengen angezeigt werden sollen, ist diese Klausel sinnvoll einzusetzen, selbst wenn sie nicht kompatibel zum SQLStandard ist: der Geschwindigkeitsvorteil rechtfertigt den Aufwand diese Klausel bedingt in einer Anwendung zu programmieren. Ein analoges Konstrukt für Oracle ist die Klausel: select * from ( select * from sample_table ) where rownum <= 200 die im Ergebnis zwar ebenfalls eine Einschränkung der Ergebnismenge bewirkt, die aber erst beim Auslesen der vollständigen Ergebnismenge der inneren Abfrage durch die äußere Abfrage erfolgt. Wenn eine solche Abfrage aufgrund der Suchbedingungen eine gesamte Tabelle durchliest (full table scan), dann wird deutlich, dass das professionellere Datenbanksystem nicht in jeder Situation das schnellere sein muß. 2.2 Funktionalität Manche Funktionen sind bei Datenbankherstellern schlichtweg aufgrund von Designentscheidungen entfallen obwohl sie sehr nützlich in der Anwendungsentwicklung sind: Als Beispiel sei die MySQL-Funktion affectedRows() genannt, die es erlaubt auch nach ändernden SQLStatements wie UPDATE und DELETE die Anzahl der betroffenen Sätze festzustellen. Eine Anwendung die gezielt nur einen Datensatz ändern will, kann mit dieser Funktion feststellen, ob dies zutrifft. SQL ist aufgrund seiner mengentheoretischen Herkunft nicht in der Lage diese Information in einem SQL-Statement zu liefern. Als Ersatzkonstrukt wird oft darauf verwiesen das Statement select count(*) zu verwenden. Diese führt allerdings zu einer Vergrößerung der Zugriffszeiten, da dieselbe Abfrage ein zweites Mal ausgeführt wird. Software- und Organisations-Service GmbH 30. November 2005 Connection - Zugriffsschicht für Datenbanken 4 2.3 Kompatibilität Weder Oracle noch MySQL sind 100%ig kompatibel zu einem SQL-Standard. Standards wie SQL92 und SQL99 sind von beiden Datenbanken nicht vollständig implementiert. Als Beispiel sei auf Left Outer JoinAbfragen verwiesen, die Oracle erst ab einer aktuellen Version 9.2 standardkonform unterstützt. Eine solche Join-Abfrage liefert zu einer Menge von Sätzen aus zwei Tabellen auch dann ein Ergebnis, wenn in der rechten Tabelle kein entsprechender Treffersatz gefunden wird. Die Oracle-Syntax hierfür lautet: select * from left_table lt, right_table rt where lt.key=rt.key(+) Die SQL99 standardkonforme Syntax lautet: select * from left_table lt left outer join right_table rt on lt.key=rt.key Dieser Zugriff ist daher ohne Rücksicht auf das eingesetzte Datenbanksystem nicht implementierbar. 2.4 Schlussfolgerung für die Abstraktion Von den vorstehenden Beispielen ausgehend könnte man meinen eine Abstraktion vom konkreten Datenbanksystem sei nicht erreichbar. Dies ist zutreffend solange der Begriff Abstraktion fordert, Datenbanken müssten hinsichtlich Ihrer Syntax gleich sein. Fordert man dagegen, dass sie sich gleich verhalten gegenüber einer Anwendung, dann lässt sich dieses Verhalten durch Implementierung einer Zugriffsschicht herstellen. Die SOS_Connection-Klassen stellen entsprechend keine Einschränkung dar hinsichtlich der Frage, welche Syntax für SQL-Statements verwendet wird, sondern standardisieren 3 - welche Methoden verfügbar sind, wie sie parametrisiert werden und welche Rückgaben sie liefern - in welchen Formaten Daten zurückgeliefert werden (scalare Typen, arrays) - in welchen Formaten SQL-Funktionen wie upper(), lower() angesprochen werden - wie Zeitstempel an die Datenbank übergeben werden - wie das Fehlermanagement implementiert ist - wie das Tracing von Datenbankaufrufen erfolgt - wie eine vergleichende Messung der Zugriffszeiten (profiling) betrieben werden kann. Unterstützte Datenbanksysteme Für folgende Datenbanksysteme sind SOS_Connection-Klassen verfügbar: Oracle ab Version 8.1.7 MySQL ab Version 3.25, SOS_Record_Connection erst ab Version 4.01 MS SQL-Server ab Version 7 ODBC-Datenbanken hostWare-Dateitypen mit Zugriff auf BS2000 und MVS Software- und Organisations-Service GmbH 30. November 2005 Connection - Zugriffsschicht für Datenbanken 4 5 Methoden 4.1 Standardisierte Aufrufe Die Methoden aller SOS_Connection-Klassen sind in gleicher Weise parametrisiert und liefern dieselben Funktionsergebnisse. Die Beschreibung der Parameter kann der API-Dokumentation im PHPDoc-Format entnommen werden. 4.1.1 connect() boolean connect ($db_user=null, $db_pass=null, $db_name=null, $db_host=null, $persistent=null ) Die Methode besorgt den Verbindungsaufbau zur Datenbank. Rückgabewert Fehlerzustand Anmerkungen Nach dem Verbindungsaufbau werden automatisch folgende Voreinstellungen vorgenommen: Datumsformate: ISO (yyyy-mm-dd hh24:mm:ss) Zahlenformate: . (Punkt) als Dezimalzeichen Transaktionen: automatischer Transaktionsbeginn, kein automatisches Transaktionsende (auto commit), nach dem Verbindungsaufbau werden evtl. offene Transaktionen mit rollback() zurückgerollt. Für PHP wird rollback() als register_shutdown-Funktion bekanntgegeben, um beim Abschluss einer Web-Seite evtl. offene Transaktionen automatisch zurückzurollen. Persistente Verbindungen: per Voreinstellung open() ist ein Alias für connect() 4.1.2 disconnect() boolean disconnect () Die Methode baut die Verbindung zur Datenbank ab. Der Aufruf wird bei persistenten Verbindungen ignoriert. Rückgabewert Fehlerzustand Anmerkungen close() ist ein Alias für disconnect() 4.1.3 get () array get ( $stmt_id=null, $sql_unquoted=null ) Die Methode liest den nächsten Satz der Ergebnismenge einer Abfrage Rückgabewert Assoziatives Array bestehend aus Feldnamen und Werten des nächsten Datensatzes, im Fehlerfall wird ein leeres Array geliefert. Software- und Organisations-Service GmbH 30. November 2005 Connection - Zugriffsschicht für Datenbanken 6 Anmerkung Die Feldnamen werden per Voreinstellung in Kleinbuchstaben geliefert; der Eigenschaft $normalize_field_name kann der Wert einer Funktion übergeben werden, z.B. "upper", wenn Feldnamen in anderer Schreibweise vereinbart werden sollen. 4.1.4 get_single () array get_single ( $sql_stmt, $sql_unquoted=null ) Die Methode liest einen Datensatz einer Abfrage Rückgabewert Assoziatives Array bestehend aus Feldnamen und Werten des nächsten Datensatzes, Null im Fehlerfall 4.1.5 get_single_value () string get_single_value ( $sql_stmt, $sql_unquoted=null ) Die Methode liest einen skalaren Wert, i.d.R. ein Feld, des ersten Satzes der Ergebnismenge einer Abfrage Rückgabewert String oder Null im Fehlerfall 4.1.6 get_single_array () array get_single_array ( $sql_stmt, $sql_unquoted=null ) Die Methode liefert ein assoziatives Array aus Feldnamen und skalarem Wert, d.h. ein Feld aller Sätze der Ergebnismenge einer Abfrage Rückgabewert Array oder Null im Fehlerfall 4.1.7 get_array () string get_array ( $sql_stmt, $sql_unquoted=null ) Die Methode liefert ein zweidimensionales Array: die erste Dimension enthält die Nummer des Ergebnissatzes, die zweite Dimension liefert Feldnamen und Wert des jeweiligen Satzes. Rückgabewert zweidimensionales Array oder Null im Fehlerfall 4.1.8 get_array_value () array get_single_array ( $sql_stmt, $sql_unquoted=null ) Die Methode liefert ein Array einfacher skalarer Wert, i.d.R. ein Feld, aller Sätze der Ergebnismenge einer Abfrage Rückgabewert Array oder Null im Fehlerfall Software- und Organisations-Service GmbH 30. November 2005 Connection - Zugriffsschicht für Datenbanken 4.1.9 7 execute () statement_id execute ( $sql_stmt) Die Methode führt ein SQL-Statement aus. Rückgabewert Handle für die Ergebnismenge oder Null im Fehlerfall 4.1.10 update_blob_from_file () boolean update_blob_from_file ( $table, $col, $file, $cond='' ) Die Methode speichert den Inhalt einer Datei in ein Datenbankfeld vom Typ BLOB. Rückgabewert Fehlerzustand 4.1.11 update_blob () boolean update_blob ( $table, $col, $data, $cond='' ) Die Methode aktualisiert den Inhalt eines Strings in einem BLOB-Feld Rückgabewert Fehlerzustand 4.1.12 create_file_from_blob () boolean create_file_from_blob ( $sql_stmt, $file_name ) Die Methode speichert den Inhalt einer Datei in ein Datenbankfeld vom Typ BLOB in einem neuen Datensatz. Rückgabewert Fehlerzustand 4.1.13 commit () boolean commit ( $immediate=0 ) Schließt eine Transaktion ab Rückgabewert Fehlerzustand Anmerkungen Der Aufruf wird bei Einsatz der Klasse SOS_History ignoriert, der Transaktionsabschluss stattdessen in der Historie gespeichert und zu einem späteren Zeitpunkt ausgeführt. Von der Klasse SOS_Profiler wird die Methode mit dem immediate-Parameter aufgerufen, um bei Einsatz der Klasse SOS_History Transaktionen im Profiler zu ermöglichen. Software- und Organisations-Service GmbH 30. November 2005 Connection - Zugriffsschicht für Datenbanken 8 4.1.14 rollback () boolean rollback () Rollt eine Transaktion zurück Rückgabewert Fehlerzustand 4.1.15 error () boolean error () Liefert den Fehlerzustand zurück Rückgabewert Fehlerzustand 4.1.16 get_error () string get_errror () Liefert den Text des letzten aufgetretenen Fehlers zurück Rückgabewert String oder Null 5 SQL-Funktionen Die nachfolgenden SQL-Funktionen werden automatisch auf die Syntax der unterstützten Datenbanksysteme abgebildet. Die Funktionsnamen werden zur Unterscheidung von SQL-Funktionen durch % präfiziert. 5.1 %lower( $string ) Liefert den Inhalt des Parameters in Kleinbuchstaben. 5.2 %upper( $string ) Liefert den Inhalt des Parameters in Großbuchstaben. 5.3 %now () Liefert einen aktuellen Zeitstempel 5.4 %timestamp ( $timestamp ) Liefert den Inhalt des übergebenen Zeitstempels aus dem Format dd.mm.yyyy hh24:mm:ss im ISO-Format yyyy-mm-dd hh24:mm:ss Software- und Organisations-Service GmbH 30. November 2005 Connection - Zugriffsschicht für Datenbanken 6 9 Fehlermanagement Die SOS_Connection-Klassen bieten die Methoden error() für den Fehlerzustand und get_error() für den Text des letzten aufgetretenen Fehlers an. Da Datenbanksysteme Fehlermeldungen häufig bei Ausführung des nächsten SQL-Statements wegwerfen, werden Fehler oft übersehen, wenn sie nicht direkt nach der Ausführung eines Statements abgefragt werden. Die Fehlermeldungen aus SOS_Connection-Klassen bleiben dagegen erhalten, bis sie mit der Methode reset_error() zurückgesetzt werden. Die Klasse SOS_Profiler speichert alle Fehlermeldungen von SOS_Connection-Klassen automatisch in einer Datenbank und macht sie für spätere Auswertungen verfügbar. 7 Tracing Die SOS_Connection-Klassen unterstützen ein einheitliches Tracing : durch Setzen der Eigenschaft $debug_level wird die Protokollierungstiefe eingestellt. Ab Stufe 3 werden alle Methodenaufrufe und Parameter von SOS_Connection-Klassen protokolliert. Ab Stufe 6 werden auch methodeninterne Datenbankaufrufe protokolliert. Das Trace-Protokoll wird durch Setzen der Eigenschaft $debug_level direkt in die Ausgabe der PHPAnwendung geschrieben. Alternativ kann durch Setzen der Eigenschaft $log_level die Ausgabe in die Datei "sos.log" im Arbeitsverzeichnis der Anwendung geleitet werden. 8 Profiling Mit der Klasse SOS_Profiler steht ein Instrument zur Performance-Messung und zur Fehlersuche in SQLStatements zur Verfügung. Alle SOS_Connection-Klassen sind für Profiling vorbereitet und liefern pro Methodenaufruf das Intervall zwischen Beginn der Ausführung eines SQL-Statements und dem Verlassen der Methode in Millisekunden. Eine vergleichende Messung von Anwendungen unter Last ist dadurch möglich. Die Klasse SOS_Profiler ist separat dokumentiert. Das Profiling wird durch Zuweisung eines Profiler-Objekts an die Eigenschaft $profiler einer SOS_Connection-Klasse aktiviert. Software- und Organisations-Service GmbH 30. November 2005