PHP Handbuch
Zurück |  | Weiter

# CXXII. PDO-Funktionen

# Einführung

Die PHP Data Objects(PDO)-Erweiterung stellt eine leichte, konsistente Schnittstelle bereit, um mit PHP auf Datenbanken zuzugreifen. Jeder Datenbanktreiber, der die PDO-Schnittstelle implementiert, kann spezifische Features als reguläre Funktionen der Erweiterung bereitstellen. Beachten Sie, dass Sie keine Funktionen der Datenbank mit PDO allein benutzen können. Sie müssen einen datenbankspezifischen PDO-Treiber benutzen, um auf eine Datenbank zuzugreifen.

PDO bietet eine Abstraktionsschicht für den Datenzugriff, das bedeutet, dass Sie, egal welche Datenbank Sie benutzen, dieselben Funktionen verwenden können, um Abfragen zu erstellen und Daten zu lesen. PDO bietet keine Abstraktion für Datenbanken. Es schreibt keine SQL-Abfragen um oder emuliert fehlende Features. Sie sollten eine komplette Abstraktionsschicht verwenden, wenn Sie diese Funktionalität benötigen.

PDO wird mit PHP 5.1 ausgeliefert und ist als PECL-Erweiterung für PHP 5.0 verfügbar. PDO benötigt die neuen OO-Features im Kern von PHP 5 und wird deswegen nicht mit früheren Versionen von PHP funktionieren.

# Installation

PHP 5.1 und höher auf Unix-Systemen

1. Wenn Sie ein PHP 5.1-Release verwenden, ist PDO bereits enthalten. Es wird automatisch angeschaltet, wenn Sie configure ausführen. Es wird empfohlen, PDO als shared module zu kompilieren, da Sie so die durch PECL bereitgestellen Updates nutzen können. Das empfohlene configure-Kommando, um PHP mit PDO zu kompilieren, sollte auch die zlib-Unterstützung (für den PEAR-Installer) aktivieren. Sie müssen eventuell auch den PDO-Treiber für die Datenbank Ihrer Wahl aktivieren. Ziehen Sie die Dokumentation für datenbankspezifische PDO-Treiber zu Rate, um mehr darüber herauszufinden, aber beachten Sie, dass Sie, wenn Sie PDO als Shared Extension bauen, auch die PDO-Treiber als Shared Extensions bauen müssen.

       ./configure --with-zlib --enable-pdo=shared

2. Nach der Installation von PDA als shared module müssen sie Ihre `php.ini`-Datei bearbeiten, damit die PDO-Erweiterung automatisch geladen wird, wenn PHP ausgeführt wird. Sie müssen dort auch alle datenbankspezifischen Treiber aktivieren. Versichern Sie sich, dass diese nach der Zeile mit pdo.so stehen, da PDO initialisiert werden muss, bevor die datenbankspezifischen Erweiterungen geladen werden können. Wenn Sie PDO und die datenbankspezifischen Erweiterungen statisch kompiliert haben, können Sie diesen Schritt überspringen.

       extension=pdo.so

3. PDO als shared module zu benutzen erlaubt Ihnen, pear upgrade pdo auszuführen, wenn neue Versionen von PDO veröffentlicht werden, ohne dass Sie PHP komplett neu kompilieren müssen. Beachten Sie, dass Sie auch die datenbankspezifischen Treiber zur gleichen Zeit aktualisieren müssen.

PHP 5.0 und höher auf Unix-Systemen

1. PDO ist als PECL-Erweiterung verfügbar auf http://pecl.php.net/package/pdo. Die Installation kann mit Hilfe des pear-Tools durchgeführt werden. Dies ist standardmäßig aktiviert, wenn sie PHP konfigurieren. Sie sollten sich vergewissern, dass PHP mit `--with-zlib` erstellt wurde, damit pear mit der komprimierten Paketdatei umgehen kann.

2. Führen Sie den folgenden Befehl aus, um die neueste stabile Version von PDO herunterzuladen, zu kompilieren und zu installieren:

       pear install pdo

3. Wenn PDO sich noch in der Beta-Phase befindet (und zur Zeit, wenn diese Zeilen geschrieben werden, ist es das noch), werden Sie dem pear-Tool explizit mitteilen müssen, dass es in Ordnung ist, das Beta-Paket zu benutzen. Statt des oben genannten Befehls benutzen Sie einfach:

       pear install pdo-beta

4. Der pear-Befehl installiert das PDO-Modul automatisch in Ihr PHP-extensions-Verzeichnis. Um die PDO-Erweiterung unter Linux oder Unix zu aktivieren, müssen Sie die folgende Zeile zur `php.ini` hinzufügen:

       extension=pdo.so

   Für weitere Informationen über das Erstellen von PECL-Paketen lesen Sie am besten das Kapitel PECL-Installation im Handbuch.

PHP 5.1 und höher unter Windows

1. PDO und alle gängigen Treiber werden mit PHP als shared module mitgeliefert und müssen nur durch Bearbeiten der Datei `php.ini` aktiviert werden:

       extension=php_pdo.dll

2. Als nächstes wählen sie die datenbankspezifischen DLL-Dateien und laden sie entweder per dl() zur Laufzeit oder aktivieren sie in der Datei `php.ini` unterhalb von `php_pdo.dll`. Zum Beispiel:

       extension=php_pdo.dll
       extension=php_pdo_firebird.dll
       extension=php_pdo_informix.dll
       extension=php_pdo_mssql.dll
       extension=php_pdo_mysql.dll
       extension=php_pdo_oci.dll
       extension=php_pdo_oci8.dll
       extension=php_pdo_odbc.dll
       extension=php_pdo_pgsql.dll
       extension=php_pdo_sqlite.dll

   Diese DLLs sollten im extension_dir des Systems vorhanden sein. Beachten Sie bitte, dass PDO_INFORMIX nur als PECL-Erweiterung verfügbar ist.

# Laufzeit Konfiguration

Das Verhalten dieser Funktionen wird durch Einstellungen in der `php.ini` beeinflusst.

Tabelle 1. PDO Configuration Options

Name | Default | Changeable | Changelog
--- | --- | --- | ---
pdo.dsn.* |  | `php.ini` only |

Weitere Details und die Definitionen der PHP_INI_*-Konstanten finden Sie im Anhang H.

Hier eine kurze Erklärung der Konfigurationsoptionen:

`pdo.dsn.*` string

  Defines DSN alias. See PDO->__construct() for thorough explanation.

# PDO-Treiber

Die folgenden Treiber implementieren momentan die PDO-Schnittstelle:

Treibername | Unterstützte Datenbanken
--- | ---
PDO_DBLIB | FreeTDS / Microsoft SQL Server / Sybase
PDO_FIREBIRD | Firebird/Interbase 6
PDO_INFORMIX | IBM Informix Dynamic Server
PDO_MYSQL | MySQL 3.x/4.x
PDO_OCI | Oracle Call Interface
PDO_ODBC | ODBC v3 (IBM DB2, unixODBC und win32 ODBC)
PDO_PGSQL | PostgreSQL
PDO_SQLITE | SQLite 3 und SQLite 2

# Verbindungen und Verwaltung der Verbindungen

Verbindungen werden durch das Erstellen von Instanzen der PDO-Basisklase erzeugt. Es ist unerheblich, welchen Treiber Sie benutzen wollen. Sie benutzen immer den PDO-Klassennamen. Der Konstruktor erwartet Parameter zur Angabe der Datenbankquelle (auch bekannt als DSN) und optional für Benutzername und Passwort (falls vorhanden).

Beispiel 1. Mit MySQL verbinden

`<?php $dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass); ?>`

Wenn es Fehler bei der Verbindung gibt, wird eine Ausnahme vom Typ `PDOException` geworfen. Sie können die Ausnahme abfangen, wenn Sie sich selbst um die Fehlerbedingung kümmern wollen, oder Sie können es einer globalen Routine zur Ausnahmebehandlung überlassen, die Sie mit set_exception_handler() konfigurieren.

Beispiel 2. Verbindungsfehler behandeln

`<?php try { $dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass); foreach ($dbh->query('SELECT * from FOO') as $row) { print_r($row); } $dbh = null; } catch (PDOException $e) { print "Error!: " . $e->getMessage() . "<br/>"; die(); } ?>`

Warnung

Wenn Ihre Anwendung die vom PDO-Konstruktor geworfene Ausnahme nicht auffängt, ist die normale Vorgehnsweise der Zend Engine, das Script zu terminieren und einen Backtrace anzuzeigen. Dieser Backtrace wird wahrscheinlich alle Details der Datenbankverbindung enthüllen, inklusive Benutzername und Passwort. Sie sind also verantwortlich, diese Ausnahme aufzufangen, entweder explizit (mit einem `catch`-Block) oder implizit mit set_exception_handler().

Bei erfolgreicher Verbindung zur Datenbank wird eine Instanz der PDO-Klasse an Ihr Script zurückgegeben. Die Verbindung bleibt während der Lebensdauer des PDO-Objekts aktiv. Um die Verbindung zu beenden, müssen Sie das Objekt löschen, indem Sie sicherstellen, dass alle Referenzen darauf gelöscht werden - das erreichen Sie, indem Sie der Variable, die das Objekt beinhaltet, `NULL` zuweisen. Wenn Sie das nicht explizit tun, schließt PHP die verbindung automatisch, wenn Ihr Script endet.

Beispiel 3. Eine Verbindung schließen

`<?php $dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass); // use the connection here // and now we're done; close it $dbh = null; ?>`

Viele Webanwendungen profitieren von persistenten Verbindungen zum Datenbankserver. Persistente Verbindungen werden nicht am Ende des Scripts geschlossen, sondern werden gecachet und wieder benutzt, wenn ein anderes Script eine Verbindung mit denselben Daten anfordert. Der Cache an persistenten Verbindungen erlaubt Ihnen, den Overhead zu vermeiden, wenn jedes mal eine neue Verbindung geöffnet wird, sobald ein Script mit der Datenbank kommunizieren muss, was sich in einer schnelleren Anwendung widerspiegelt.

Beispiel 4. Persistente Verbindungen

`<?php $dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass, array( PDO::ATTR_PERSISTENT => true )); ?>`

> Anmerkung: Wenn Sie den PDO-ODBC-Treiber benutzen und Ihre ODBC-Bibliotheken ODBC Connection Pooling unterstützen (unixODBC und Windows etwa, es könnte auch andere geben), dann wird empfohlen, dass sie keine persistenten PDO-Verbindungen benutzen, sondern das Cachen der Verbindungen der ODBC Connection Pooling-Schicht überlassen. Der ODBC Connection Pool wird mit anderen Modulen im Prozess geteilt. Wenn PDO also angewiesen wird die Verbindung zu cachen, wird diese Verbindung nie dem ODBC Connection Pool zurückgegeben, was darin resultiert, dass zusätzliche Verbindungen aufgebaut werden, um jene anderen Module zu bedienen.

# Transaktionen und auto-commit

Jetzt, wo Sie via PDO verbunden sind, müssen Sie sich bewusst machen, wie PDO Transaktionen verwaltet, bevor Sie anfangen, Abfragen auszuführen. Falls Sie noch niemit Transaktionen zu tun hatten, diese bieten 4 wichtige Features: Atomizität, Konsistenz (Consistency), Isolation und Dauerhaftigkeit (Durability) (ACID). Einfach gesagt wird alles in einer Transaktion, auch wenn es in Einzelschritten ausgeführt wird, garantiert in sicherer Weise in die Datenbank eingetragen, ohne Beeinträchtigung durch andere Verbindungen, wenn es abgeschickt wird. Aktivitäten in Transaktionen können auch automatisch annulliert werden (wenn Sie es noch nicht abgeschickt haben), was Fehlerbehandlung in Ihren Scripts einfacher macht.

Transaktionen werden typischerweise implementiert, indem Ihre Menge an Änderungen "aufgespart" wird und dann in einem Rutsch abgearbeitet werden. Das hat den netten Nebeneffekt, dass die Effizienz der Aktualisierungen drastisch erhöht wird. In anderen Worten können Transaktionen Ihre Scripts schneller und möglicherweise auch robuster machen. Aber Sie müssen sie korrekt verwenden, um davon zu profitieren.

Unglücklicherweise unterstützt nicht jede Datenbank Transaktionen, deswegen muss PDO in einem "auto-commit" genannten Modus laufen, wenn Sie die Verbindung zum ersten Mal öffnen. "Auto-commit" bedeutet, dass jede Abfrage, die Sie ausführen ihre eigene implizite Transaktion besitzt, wenn die Datenbank das unterstützt, oder keine Transaktion, wenn die Datenbank keine Transaktionen unterstützt. Wenn Sie eine Transaktion benötigen, müssen Sie eine mit der Methode PDO::beginTransaction() initiieren. Wenn der zu Grunde liegende Treiber keine Transaktionen unterstützt, wird eine `PDOException` geworfen (unbeachtet Ihrer Einstellungen zur Fehlerbehandlung: dies ist immer eine ernste Fehlerbedingung). Wenn Sie dann in einer Transaktion sind, können Sie PDO::commit() oder PDO::rollBack() benutzen, um die Transaktion abzuschließen, abhängig vom Erfolg des Codes, den Sie während der Transaktion ausgeführt haben.

Wenn das Script endet oder die Verbindung im Begriff ist, geschlossen zu werden und Sie eine Transaktion ausstehen haben, wird PDO automatisch einen Rollback durchführen. Dies ist eine Sicherheitsmaßnahme, um Inkonsistenzen in dem Fall, wo das Script unerwartet beendet wird, zu vermeiden - wenn Sie die Transaktion nicht explizit ausgeführt haben, wird angenommen, dass etwas schiefgegangen ist, deswegen wird zur Sicherheit ein Rollback durchgeführt.

Warnung
Der automatische Rollback wird nur durchgeführt, wenn Sie die Transaktion per PDO::beginTransaction() starten. Wenn Sie manuell eine Abfrage ausführen, die eine Transaktion startet, kann PDO nichts davon wissen und kann deswegen auch keinen Rollback durchführen, wenn etwas schiefgeht.

Beispiel 5. Mehrere Abfragen in einer Transaktion

Im folgenden Beispiel nehmen wir an, dass wir einen Satz von Einträgen für einen neuen Angestellten eintragen wollen, dem die ID-Nummer 23 zugeordnet wurde. Zusätzlich zur Angabe der Basisdaten für diese Person müssen wir auch ihr Gehalt festhalten. Es ist ziemlich einfach, zwei getrennte Aktualisierungen durchzuführen, aber indem wir sie in PDO::beginTransaction() und PDO::commit() einschließen, garantieren wir, dass niemand anderes diese Änderungen sieht, bis sie komplett sind. Wenn etwas schiefgeht, wird der `catch`-Block alle seit Beginn der Transaktion durchgeführten Änderungen rückgängig machen und dann eine Fehlermeldung ausgeben.

`<?php
try {
$dbh = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2',
array(PDO::ATTR_PERSISTENT => true));
echo "Connected\n";
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->beginTransaction();
$dbh->exec("insert into staff (id, first, last) values (23, 'Joe', 'Bloggs')");
$dbh->exec("insert into salarychange (id, amount, changedate)
values (23, 50000, NOW())");
$dbh->commit();
} catch (Exception $e) {
$dbh->rollBack();
echo "Failed: " . $e->getMessage();
}
?>`

Sie sind nicht darauf beschränkt, Änderungen in einer Transaktion durchzuführen. Sie können auch komplexe Abfragen ausführen um Daten zu erhalten, und diese Informationen etwa dazu benutzen, mehr Änderungen und Abfragen zu erzeugen. Während die Transaktion aktiv ist, kann garantiert niemand anderes Änderungen durchführen, während Sie bei der Arbeit sind. Um ehrlich zu sein, stimmt das nicht 100%, aber es ist für den Anfang ausreichend, falls Sie noch nie von Transaktionen gehört haben.

# Prepared Statements und Stored Procedures

Viele der ausgereifteren Datenbanken unterstützen das Konzept der Prepared Statements. Was ist das? Sie können sie sich als eine Art von kompiliertem Template für SQL vorstellen, das durch variable Parameter angepasst werden kann. Prepared Statements haben zwei wichtige Vorteile:

- Die Abfrage muss nur einmal geparset (oder vorbereitet) werden, kann dann aber mehrere Male mit denselben oder anderen Parametern ausgeführt werden. Wenn die Abfrage vorbereitet wird, kann die Datenbank ihre Vorgehensweise zur Ausführung der Abfrage analysieren, kompilieren und optimieren. Für komplexe Abfragen kann dieser Vorgang genug Zeit benötigen, dass es Ihre Anwendung merklich verlangsamt, wenn Sie dieselbe Abfrage oft mit verschiedenen Parametern wiederholen. Mit einem Prepared Statement vermeiden Sie den Zyklus der Analyse/Kompilierung/Optimierung. Kurz gesagt benötigen Prepared Statements weniger Ressourcen und laufen deswegen schneller.

- Die Parameter für Prepared Statements müssen nicht maskiert werden. Der Treiber übernimmt das für Sie. Wenn Ihre Anwendung ausschließlich Prepared Statements benutzt, können Sie sicher sein, dass keine SQL-Injection auftreten wird. (Wenn Sie aber trotzdem andere Teile der Abfrage aus nicht zuverlässigen Eingaben generieren, sind Sie immer noch gefährdet.)

Prepared Statements sind so nützlich, dass sie das einzige Feature sind, das PDO auch für Treiber emulieren wird, die diese nicht unterstützen. Das garantiert, dass Sie unabhängig von den Möglichkeiten der Datenbank dieselbe Art des Datenzugriffs nutzen können.

Beispiel 6. Wiederholte Inserts mit Prepared Statements

Dieses Beispiel führt eine INSERT-Abfrage durch, indem ein `name` und ein `value` für die benannten Platzhalter eingesetzt werden.

`<?php $stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (:name, :value)"); $stmt->bindParam(':name', $name); $stmt->bindParam(':value', $value); // insert one row $name = 'one'; $value = 1; $stmt->execute(); // insert another row with different values $name = 'two'; $value = 2; $stmt->execute(); ?>`

Beispiel 7. Wiederholte Inserts mit Prepared Statements

Dieses Beispiel führt eine INSERT-Abfrage durch, indem ein `name` und ein `value` für die positionsabhängigen `?`-Platzhalter eingesetzt werden.

`<?php $stmt = $dbh->prepare("INSERT INTO REGISTRY (name, value) VALUES (?, ?)"); $stmt->bindParam(1, $name); $stmt->bindParam(2, $value); // insert one row $name = 'one'; $value = 1; $stmt->execute(); // insert another row with different values $name = 'two'; $value = 2; $stmt->execute(); ?>`

Beispiel 8. Abfragen von Daten mit Prepared Statements

Dieses Beispiel ruft Daten basierend auf einem Schlüsselwert ab, der von einem Formular geliefert wird. Die Benutzereingabe wird automatisch maskiert, deswegen gibt es kein Risiko eines SQL-Injection-Angriffs.

`<?php $stmt = $dbh->prepare("SELECT * FROM REGISTRY where name = ?"); if ($stmt->execute(array($_GET['name']))) { while ($row = $stmt->fetch()) { print_r($row); } } ?>`

Wenn es der Datenbanktreiber unterstützt, können Sie auch Parameter für die Ausgabe einführen, ähnlich der Eingabe. Ausgabeparameter werden typischerweise benutzt, um Werte von Stored Procedures abzurufen. Ausgabeparameter sind etwas komplexer in der Verwendung als Eingabeparameter, weil Sie wissen müssen, wie groß ein gegebener Parameter sein könnte, wenn Sie ihn einführen. Wenn der Wert sich als größer herausstellt als die vorgeschlagene Größe, wird ein Fehler ausgelöst.

Beispiel 9. Eine Stored Procedure mit einem Ausgabeparameter aufrufen

`<?php $stmt = $dbh->prepare("CALL sp_returns_string(?)"); $stmt->bindParam(1, $return_value, PDO::PARAM_STR, 4000); // call the stored procedure $stmt->execute(); print "procedure returned $return_value\n"; ?>`

Sie können auch Parameter angeben, die Werte für Eingabe und Ausgabe enthalten. Die Syntax ist ähnlich den Ausgabeparametern. In diesem nächsten Beispiel wird die Zeichenkette 'hello' der Stored Procedure übergeben und wenn diese etwas zurückgibt, wird 'hello' durch den Rückgabewert der Stored procedure ersetzt.

Beispiel 10. Eine Stored Procedure mit einem Eingabe-/Ausgabe-Parameter aufrufen

`<?php $stmt = $dbh->prepare("CALL sp_takes_string_returns_string(?)"); $value = 'hello'; $stmt->bindParam(1, $value, PDO::PARAM_STR|PDO::PARAM_INPUT_OUTPUT, 4000); // call the stored procedure $stmt->execute(); print "procedure returned $value\n"; ?>`

# Fehler und Fehlerbehandlung

PDO bietet Ihnen die Wahl unter 3 verschiedenen Strategien zur Fehlerbehandlung, um Ihrem Stil der Anwendungsentwicklung gerecht zu werden.

- `PDO::ERRMODE_SILENT`

  Das ist die Standardmethode. PDO setzt einfach den Fehler-Code, damit Sie ihn mit den Methoden PDO::errorCode() und PDO::errorInfo() sowohl im Statement- als auch im Datenbank-Objekt überprüfen können. Wenn der Fehler aus einem Aufruf eines Statement-Objekts hervorging, würden Sie die Methoden PDOStatement::errorCode() oder PDOStatement::errorInfo() des Objekts aufrufen. Wenn der Fehler aus einem Aufruf des Datenbank-Objekts hervorging, würden Sie diese Methoden des Datenbank-Objekts aufrufen.

- `PDO::ERRMODE_WARNING`

  Zusätzlich zum Setzen des Fehler-Codes wird PDO eine traditionelle E_WARNING-Nachricht ausgeben. Diese Einstellung ist nützlich während des Debuggens/Testens, wenn Sie sehen wollen, welche Probleme aufgetreten sind, ohne den Ablauf der Anwendung zu unterbrechen.

- `PDO::ERRMODE_EXCEPTION`

  Zusätzlich zum Setzen des Fehler-Codes wirft PDO eine PDOException und setzt deren Eigenschaften so, dass sie den Fehler-Code und Fehlerinformationen widergeben. Diese Einstellung ist auch nützlich während des Debuggens, da sie das Script am Ort des Fehlers gewissermaßen "sprengt" und sehr schnell mögliche Problemstellen in Ihrem Code aufzeigt. (Zur Erinnerung: Transaktionen bekommen automatisch einen Rollback, wenn eine Ausnahme das Script beendet.)

  Diese Einstellung ist auch nützlich, da Sie ihre Fehlerbehandlung klarer als mit traditionellen PHP-Warnungen strukturireren können und mit weniger Code und Verschachtelung als im stillen Modus mit expliziter Überprüfung des Rückgabewertes jedes einzelnen Datenbankaufrufes.

  Unter Ausnahmen finden Sie weitere Informationen über Ausnahmen in PHP.

PDO benutzt Fehler-Codes nach SQL-92 SQLSTATE. Individuelle PDO-Treiber sind selbst verantwortlich, ihre nativen Fehler-Codes in die entsprechenden SQLSTATE-Pendants umzuwandeln. Die Methode PDO::errorCode() gibt einen einzelnen SQLSTATE-Code zurück. Wenn Sie genauere Informationen über einen Fehler benötigen, bietet PDO auch die Methode PDO::errorInfo(), die ein Array zurückgibt, das den SQLSTATE-Code, den treiberspezifischen Fehler-Code und die treiberspezifische Fehlermeldung enthält.

# Large Objects (LOBs)

Es könnte an irgendeinem Punkt in Ihrer Anwendung passieren, dass Sie eine "große" Menge an Daten in Ihrer Datenbank ablegen müssen. Groß bedeutet typischerweise "etwa 4kb oder mehr", obwohl manche Datenbanken spielend bis zu 32kb bearbeiten können, bevor das als "groß" zählt. Large Objects können aus Text oder Binärdaten bestehen. PDO erlaubt Ihnen, mit diesem großen Datentyp zu arbeiten, indem Sie `PDO::PARAM_LOB` als Typ in Ihren Methodenaufrufen von PDOStatement::bindParam() oder PDOStatement::bindColumn() benutzen. `PDO::PARAM_LOB` veranlasst PDO, die Daten als Stream zu behandeln, so dass Sie diese mit Hilfe der PHP Streams-API bearbeiten können.

Beispiel 11. Ein Bild aus einer Datenbank anzeigen

Dieses Beispiel weist das LOB der Variable namens $lob zu und sendet es mittels fpassthru() an den Browser. Weil das LOB als Stream dargestellt wird, können Funktionen wie fgets(), fread() und stream_get_contents() damit benutzt werden.

`<?php $db = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2'); $stmt = $db->prepare("select contenttype, imagedata from images where id=?"); $stmt->execute(array($_GET['id'])); $stmt->bindColumn(1, $type, PDO::PARAM_STR, 256); $stmt->bindColumn(2, $lob, PDO::PARAM_LOB); $stmt->fetch(PDO::FETCH_BOUND); header("Content-Type: $type"); fpassthru($lob); ?>`

Beispiel 12. Ein Bild in eine Datenbank einfügen

Dieses Beispiel öffnet eine Datei und übergibt das File-Handle an PDO, damit sie als LOB eingefügt wird. PDO wird sein Möglichstes tun, den Inhalt der Datei auf möglichst effiziente Weise in die Datenbank zu bekommen.

`<?php
$db = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2');
$stmt = $db->prepare("insert into images (id, contenttype, imagedata) values (?, ?, ?)");
$id = get_new_id(); // some function to allocate a new ID
// assume that we are running as part of a file upload form
// You can find more information in the PHP documentation
$fp = fopen($_FILES['file']['tmp_name'], 'rb');
$stmt->bindParam(1, $id);
$stmt->bindParam(2, $_FILES['file']['type']);
$stmt->bindParam(3, $fp, PDO::PARAM_LOB);
$stmt->beginTransaction();
$stmt->execute();
$stmt->commit();
?>`

Beispiel 13. Ein Bild in eine Datenbank einfügen: Oracle

Oracle erfordert eine leicht unterschiedliche Syntax, um ein LOB aus einer Datei einzufügen. Es ist auch unumgänglich, dass Sie diesen Insert innerhalb einer Transaktion durchführen, andernfalls wird Ihr frisch eingefügtes LOB mit einer Länge von 0 als Teil des impliziten commits, der beim Ausführen der Abfrage passiert, gespeichert.

`<?php
$db = new PDO('oci:', 'scott', 'tiger');
$stmt = $db->prepare("insert into images (id, contenttype, imagedata) " .
"VALUES (?, ?, EMPTY_BLOB()) RETURNING imagedata INTO ?");
$id = get_new_id(); // some function to allocate a new ID
// assume that we are running as part of a file upload form
// You can find more information in the PHP documentation
$fp = fopen($_FILES['file']['tmp_name'], 'rb');
$stmt->bindParam(1, $id);
$stmt->bindParam(2, $_FILES['file']['type']);
$stmt->bindParam(3, $fp, PDO::PARAM_LOB);
$stmt->beginTransaction();
$stmt->execute();
$stmt->commit();
?>`

# Vordefinierte Klassen

## PDO

Stellt eine Verbindung zwischen PHP und einem Datenbankserver dar.

### Konstruktor

- PDO - erstellt ein neues PDO-Objekt

### Methoden

- beginTransaction - startet eine Transaktion

- commit - schliesst eine Transaktion ab

- errorCode - fragt einen Fehler-Code, falls es einen gibt, von der Datenbank ab

- errorInfo - fragt ein Array mit Fehlerinformationen, wenn es welche gibt, von der Datenbank ab

- exec - führt ein SQL-Statement aus und gibt die Anzahl der betroffenen Zeilen zurück

- getAttribute - fragt ein Attribut der Datenbankverbindung ab

- lastInsertId - fragt den Wert der letzten Zeile ab, die in eine Tabelle eingefügt wurde

- prepare - bereitet ein SQL-Statement zur Ausführung vor

- query - führt ein SQL-Statement aus und gibt eine Ergebnismenge zurück

- quote - gibt eine maskierte Version einer zeichenkette zur Benutzung in SQL-Statements zurück

- rollBack - Rollback einer Transaktion durchführen

- setAttribute - setzt ein Attribut der Datenbankverbindung

## PDOStatement

Stellt ein Prepared Statement dar und nach der Ausführung desselben eine zugeordnete Ergebnismenge

### Methoden

- bindColumn - bindet eine PHP-Variable an eine Ausgabe-Spalte in der Ergebnismenge

- bindParam - bindet eine PHP-Variable an einen Parameter im Prepared Statement

- bindValue - bindet einen Wert an einen Parameter im Prepared Statement

- closeCursor - schließt den Cursor und erlaubt die erneute Ausführung des Statements

- columnCount - gibt die Anzahl der Spalten in der Ergebnismenge zurück

- errorCode - fragt einen Fehler-Code, falls es einen gibt, vom Statement ab

- errorInfo - fragt ein Array von Fehlerinformationen, falls es welche gibt, vom Statement ab

- execute - führt ein Prepared Statement aus

- fetch - holt eine Zeile aus einer Ergebnismenge

- fetchAll - holt ein Array mit allen Zeilen einer Ergebnismenge

- fetchColumn - gibt die Daten einer einzelnen Spalte der Ergebnismenge zurück

- getAttribute - fragt ein Attribut von PDOStatement ab

- getColumnMeta - fragt Metadaten für eine Spalte in der Ergebnismenge ab

- nextRowset - fragt die nächste Zeilenmenge (Ergebnismenge) ab

- rowCount - gibt die Anzahl der Zeilen zurück, die durch die Ausführung eines SQL-Statements betroffen wurden

- setAttribute - setzt ein Attribut von PDOStatement

- setFetchMode - setzt die Methode zur Abfrage für ein PDOStatement

## PDOException

Stellt einen Fehler dar, der von PDO ausgelöst wird. Sie sollten selbst keine PDOException in Ihrem eigenen Code werfen. Unter Ausnahmen finden Sie weitere Informationen über Ausnahmen in PHP.

Beispiel 14. The PDOException class

`<?php class PDOException extends Exception { public $errorInfo = null; // corresponds to PDO::errorInfo() // or PDOStatement::errorInfo() protected $message; // textual error message // use Exception::getMessage() to access it protected $code; // SQLSTATE error code // use Exception::getCode() to access it } ?>`

# Vordefinierte Konstanten

Folgende Konstanten werden von dieser Erweiterung definiert und stehen nur zur Verfügung, wenn die Erweiterung entweder statisch in PHP kompiliert oder dynamisch zur Laufzeit geladen wurde.

Warnung
PDO uses class constants since PHP 5.1. Prior releases use global constants in the form `PDO_PARAM_BOOL`.

`PDO::PARAM_BOOL` (integer)

  Represents a boolean data type.

`PDO::PARAM_NULL` (integer)

  Represents the SQL NULL data type.

`PDO::PARAM_INT` (integer)

  Represents the SQL INTEGER data type.

`PDO::PARAM_STR` (integer)

  Represents the SQL CHAR, VARCHAR, or other string data type.

`PDO::PARAM_LOB` (integer)

  Represents the SQL large object data type.

`PDO::PARAM_STMT` (integer)

  Represents a recordset type. Not currently supported by any drivers.

`PDO::PARAM_INPUT_OUTPUT` (integer)

  Specifies that the parameter is an INOUT parameter for a stored procedure. You must bitwise-OR this value with an explicit PDO::PARAM_* data type.

`PDO::FETCH_LAZY` (integer)

  Specifies that the fetch method shall return each row as an object with variable names that correspond to the column names returned in the result set. PDO::FETCH_LAZY creates the object variable names as they are accessed.

`PDO::FETCH_ASSOC` (integer)

  Specifies that the fetch method shall return each row as an array indexed by column name as returned in the corresponding result set. If the result set contains multiple columns with the same name, PDO::FETCH_ASSOC returns only a single value per column name.

`PDO::FETCH_NAMED` (integer)

  Specifies that the fetch method shall return each row as an array indexed by column name as returned in the corresponding result set. If the result set contains multiple columns with the same name, PDO::FETCH_NAMED returns an array of values per column name.

`PDO::FETCH_NUM` (integer)

  Specifies that the fetch method shall return each row as an array indexed by column number as returned in the corresponding result set, starting at column 0.

`PDO::FETCH_BOTH` (integer)

  Specifies that the fetch method shall return each row as an array indexed by both column name and number as returned in the corresponding result set, starting at column 0.

`PDO::FETCH_OBJ` (integer)

  Specifies that the fetch method shall return each row as an object with property names that correspond to the column names returned in the result set.

`PDO::FETCH_BOUND` (integer)

  Specifies that the fetch method shall return TRUE and assign the values of the columns in the result set to the PHP variables to which they were bound with the PDOStatement::bindParam() or PDOStatement::bindColumn() methods.

`PDO::FETCH_COLUMN` (integer)

  Specifies that the fetch method shall return only a single requested column from the next row in the result set.

`PDO::FETCH_CLASS` (integer)

  Specifies that the fetch method shall return a new instance of the requested class, mapping the columns to named properties in the class.

`PDO::FETCH_INTO` (integer)

  Specifies that the fetch method shall update an existing instance of the requested class, mapping the columns to named properties in the class.

`PDO::FETCH_FUNC` (integer)

`PDO::FETCH_GROUP` (integer)

`PDO::FETCH_UNIQUE` (integer)

`PDO::FETCH_CLASSTYPE` (integer)

`PDO::FETCH_SERIALIZE` (integer)

  Available since PHP 5.1.0.

`PDO::FETCH_PROPS_LATE` (integer)

  Available since PHP 5.2.0

`PDO::ATTR_AUTOCOMMIT` (integer)

  If this value is `FALSE`, PDO attempts to disable autocommit so that the connection begins a transaction.

`PDO::ATTR_PREFETCH` (integer)

  Setting the prefetch size allows you to balance speed against memory usage for your application. Not all database/driver combinations support setting of the prefetch size. A larger prefetch size results in increased performance at the cost of higher memory usage.

`PDO::ATTR_TIMEOUT` (integer)

  Sets the timeout value in seconds for communications with the database.

`PDO::ATTR_ERRMODE` (integer)

  See the Errors and error handling section for more information about this attribute.

`PDO::ATTR_SERVER_VERSION` (integer)

  This is a read only attribute; it will return information about the version of the database server to which PDO is connected.

`PDO::ATTR_CLIENT_VERSION` (integer)

  This is a read only attribute; it will return information about the version of the client libraries that the PDO driver is using.

`PDO::ATTR_SERVER_INFO` (integer)

  This is a read only attribute; it will return some meta information about the database server to which PDO is connected.

`PDO::ATTR_CONNECTION_STATUS` (integer)

`PDO::ATTR_CASE` (integer)

  Force column names to a specific case specified by the PDO::CASE_* constants.

`PDO::ATTR_CURSOR_NAME` (integer)

  Get or set the name to use for a cursor. Most useful when using scrollable cursors and positioned updates.

`PDO::ATTR_CURSOR` (integer)

  Selects the cursor type. PDO currently supports either `PDO::CURSOR_FWDONLY` and `PDO::CURSOR_SCROLL`. Stick with `PDO::CURSOR_FWDONLY` unless you know that you need a scrollable cursor.

`PDO::ATTR_DRIVER_NAME` (string)

  Returns the name of the driver.

  Beispiel 15. using PDO::ATTR_DRIVER_NAME

  `<?php if ($db->getAttribute(PDO::ATTR_DRIVER_NAME) == 'mysql') { echo "Running on mysql; doing something mysql specific here\n"; } ?>`

`PDO::ATTR_ORACLE_NULLS` (integer)

  Convert empty strings to SQL NULL values on data fetches.

`PDO::ATTR_PERSISTENT` (integer)

  Request a persistent connection, rather than creating a new connection. See Connections and Connection management for more information on this attribute.

`PDO::ATTR_STATEMENT_CLASS` (integer)

`PDO::ATTR_FETCH_CATALOG_NAMES` (integer)

  Prepend the containing catalog name to each column name returned in the result set. The catalog name and column name are separated by a decimal (.) character. Support of this attribute is at the driver level; it may not be supported by your driver.

`PDO::ATTR_FETCH_TABLE_NAMES` (integer)

  Prepend the containing table name to each column name returned in the result set. The table name and column name are separated by a decimal (.) character. Support of this attribute is at the driver level; it may not be supported by your driver.

`PDO::ATTR_STRINGIFY_FETCHES` (integer)

`PDO::ATTR_MAX_COLUMN_LEN` (integer)

`PDO::ATTR_DEFAULT_FETCH_MODE` (integer)

  Available since PHP 5.2.0

`PDO::ATTR_EMULATE_PREPARES` (integer)

  Available since PHP 5.1.3.

`PDO::ERRMODE_SILENT` (integer)

  Do not raise an error or exception if an error occurs. The developer is expected to explicitly check for errors. This is the default mode. See Errors and error handling for more information about this attribute.

`PDO::ERRMODE_WARNING` (integer)

  Issue a PHP E_WARNING message if an error occurs. See Errors and error handling for more information about this attribute.

`PDO::ERRMODE_EXCEPTION` (integer)

  Throw a PDOException if an error occurs. See Errors and error handling for more information about this attribute.

`PDO::CASE_NATURAL` (integer)

  Leave column names as returned by the database driver.

`PDO::CASE_LOWER` (integer)

  Force column names to lower case.

`PDO::CASE_UPPER` (integer)

  Force column names to upper case.

`PDO::NULL_NATURAL` (integer)

`PDO::NULL_EMPTY_STRING` (integer)

`PDO::NULL_TO_STRING` (integer)

`PDO::FETCH_ORI_NEXT` (integer)

  Fetch the next row in the result set. Valid only for scrollable cursors.

`PDO::FETCH_ORI_PRIOR` (integer)

  Fetch the previous row in the result set. Valid only for scrollable cursors.

`PDO::FETCH_ORI_FIRST` (integer)

  Fetch the first row in the result set. Valid only for scrollable cursors.

`PDO::FETCH_ORI_LAST` (integer)

  Fetch the last row in the result set. Valid only for scrollable cursors.

`PDO::FETCH_ORI_ABS` (integer)

  Fetch the requested row by row number from the result set. Valid only for scrollable cursors.

`PDO::FETCH_ORI_REL` (integer)

  Fetch the requested row by relative position from the current position of the cursor in the result set. Valid only for scrollable cursors.

`PDO::CURSOR_FWDONLY` (integer)

  Create a PDOStatement object with a forward-only cursor. This is the default cursor choice, as it is the fastest and most common data access pattern in PHP.

`PDO::CURSOR_SCROLL` (integer)

  Create a PDOStatement object with a scrollable cursor. Pass the PDO::FETCH_ORI_* constants to control the rows fetched from the result set.

`PDO::ERR_NONE` (string)

  Corresponds to SQLSTATE '00000', meaning that the SQL statement was successfully issued with no errors or warnings. This constant is for your convenience when checking PDO::errorCode() or PDOStatement::errorCode() to determine if an error occurred. You will usually know if this is the case by examining the return code from the method that raised the error condition anyway.

`PDO::PARAM_EVT_ALLOC` (integer)

  Allocation event

`PDO::PARAM_EVT_FREE` (integer)

  Deallocation event

`PDO::PARAM_EVT_EXEC_PRE` (integer)

  Event triggered prior to execution of a prepared statement.

`PDO::PARAM_EVT_EXEC_POST` (integer)

  Event triggered subsequent to execution of a prepared statement.

`PDO::PARAM_EVT_FETCH_PRE` (integer)

  Event triggered prior to fetching a result from a resultset.

`PDO::PARAM_EVT_FETCH_POST` (integer)

  Event triggered subsequent to fetching a result from a resultset.

`PDO::PARAM_EVT_NORMALIZE` (integer)

  Event triggered during bound parameter registration allowing the driver to normalize the parameter name.

Zurück | Zum Anfang | Weiter
PDF_utf8_to_utf16 | Nach oben | PDO->beginTransaction()