Signatur
Beschreibung
Mit pg_lo_open() wird ein bereits existierendes PostgreSQL Large Object geöffnet, das über seine OID (Object Identifier) identifiziert wird. Das zurückgegebene Handle kann anschließend mit Funktionen wie pg_lo_read(), pg_lo_write(), pg_lo_seek() und pg_lo_close() verwendet werden, um binäre oder große Textdaten direkt in der Datenbank zu lesen und zu schreiben.
Der Parameter $mode bestimmt den Zugriffsmodus: 'r' öffnet das Objekt zum Lesen, 'w' zum Schreiben und 'rw' für Lesen und Schreiben. Nur der jeweils passende Modus sollte verwendet werden, um unbeabsichtigte Datenverluste oder -fehler zu vermeiden.
Wichtig: Alle Large-Object-Operationen müssen innerhalb einer Transaktion stattfinden. Ein pg_query($conn, 'BEGIN') vor dem Öffnen und ein COMMIT nach dem Schließen sind zwingend erforderlich, sonst schlägt die Operation fehl oder das Handle wird ungültig.
Large Objects eignen sich besonders für das Speichern großer Binärdaten (z. B. Bilder, Dokumente) in PostgreSQL, wenn ein streaming-artiger, positionsorientierter Zugriff gewünscht wird – im Gegensatz zu bytea-Spalten, bei denen das gesamte Datum auf einmal geladen wird.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $connection Pflicht | PgSql\Connection | Eine aktive PostgreSQL-Datenbankverbindung, wie sie von pg_connect() oder pg_pconnect() zurückgegeben wird. |
|
| $oid Pflicht | int | Die OID (Object Identifier) des Large Objects, das geöffnet werden soll. Diese wird z. B. beim Erstellen mit pg_lo_create() oder beim Importieren mit pg_lo_import() zurückgegeben. |
|
| $mode Pflicht | string | Zugriffsmodus: 'r' für Nur-Lesen, 'w' für Nur-Schreiben, 'rw' für Lesen und Schreiben. |
Rückgabewert
PgSql\Lob-Handle zurück, das für weitere Large-Object-Operationen verwendet werden kann, oder false bei einem Fehler (z. B. ungültige OID oder fehlende Transaktion).Beispiele
Large Object lesen
<?php
$conn = pg_connect('host=localhost dbname=testdb user=postgres password=secret');
if (!$conn) {
die('Verbindung fehlgeschlagen');
}
// OID eines vorhandenen Large Objects (z. B. aus einer Tabelle gelesen)
$oid = 12345;
// Transaktion starten (zwingend erforderlich!)
pg_query($conn, 'BEGIN');
$lo = pg_lo_open($conn, $oid, 'r');
if ($lo === false) {
pg_query($conn, 'ROLLBACK');
die('Large Object konnte nicht geöffnet werden');
}
$inhalt = pg_lo_read($lo, 8192);
echo 'Gelesene Bytes: ' . strlen($inhalt) . PHP_EOL;
pg_lo_close($lo);
pg_query($conn, 'COMMIT');
pg_close($conn);
Large Object erstellen und beschreiben
<?php
$conn = pg_connect('host=localhost dbname=testdb user=postgres password=secret');
if (!$conn) {
die('Verbindung fehlgeschlagen');
}
pg_query($conn, 'BEGIN');
// Neues Large Object anlegen
$oid = pg_lo_create($conn);
echo 'Neue OID: ' . $oid . PHP_EOL;
// Zum Schreiben öffnen
$lo = pg_lo_open($conn, $oid, 'w');
if ($lo === false) {
pg_query($conn, 'ROLLBACK');
die('Öffnen fehlgeschlagen');
}
$daten = 'Binärdaten oder langer Text...';
$geschrieben = pg_lo_write($lo, $daten);
echo 'Geschriebene Bytes: ' . $geschrieben . PHP_EOL;
pg_lo_close($lo);
pg_query($conn, 'COMMIT');
// OID in einer Anwendungstabelle speichern
pg_query($conn, "INSERT INTO dokumente (lo_oid) VALUES ($oid)");
pg_close($conn);
// Wichtig · Fallstricke
Transaktionspflicht: PostgreSQL erfordert, dass alle Large-Object-Operationen innerhalb einer expliziten Transaktion ausgeführt werden. Ohne vorheriges BEGIN schlägt pg_lo_open() entweder fehl oder das Handle verhält sich unerwartet. Vergessen Sie nicht, die Transaktion mit COMMIT oder bei Fehlern mit ROLLBACK abzuschließen.
Sicherheit: Die OID sollte niemals direkt aus Benutzereingaben übernommen werden, ohne sie zu validieren, da sonst beliebige Large Objects in der Datenbank gelesen oder überschrieben werden könnten. Nutzen Sie parametrisierte Abfragen oder zumindest intval(), um die OID auf einen gültigen Integer zu beschränken.
PHP 8.1+: Ab PHP 8.1 gibt die Funktion ein PgSql\Lob-Objekt zurück anstatt einer Ressource. Code, der is_resource() zum Prüfen des Handles verwendet, muss entsprechend angepasst werden.