Signatur
Beschreibung
pg_lo_read_all() liest den vollständigen Inhalt eines geöffneten PostgreSQL Large Objects (LOB) und schreibt ihn direkt in den PHP-Ausgabepuffer. Die Funktion gibt die Anzahl der gelesenen Bytes zurück. Sie ist besonders nützlich, wenn binäre oder große Dateien (Bilder, PDFs, Archiv-Dateien usw.) aus einer PostgreSQL-Datenbank direkt an den Client gestreamt werden sollen, ohne den Umweg über eine PHP-Variable zu nehmen.
Bevor pg_lo_read_all() aufgerufen wird, muss das Large Object mit pg_lo_open() geöffnet worden sein, und es muss sich innerhalb einer aktiven Transaktion befinden – Large Objects in PostgreSQL sind nur innerhalb von Transaktionen zugänglich. Die Transaktion wird typischerweise mit pg_query($conn, 'BEGIN') gestartet.
Im Unterschied zu pg_lo_read(), das den Inhalt als PHP-String zurückgibt, schreibt pg_lo_read_all() den Inhalt direkt in den Output-Stream. Das spart Arbeitsspeicher bei großen Objekten und eignet sich optimal für Download-Skripte. Um ungewollte Ausgabe vor dem LOB-Inhalt zu vermeiden, sollten etwaige Output-Buffer vorher geleert werden.
Die Funktion erwartet ein PgSql\Lob-Objekt, das von pg_lo_open() zurückgegeben wird. Ab PHP 8.1 ist dieser Rückgabewert ein echtes Objekt statt einer Ressource.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $lob Pflicht | PgSql\Lob | Ein geöffnetes Large-Object-Handle, das zuvor mit pg_lo_open() innerhalb einer aktiven Transaktion erzeugt wurde. |
Rückgabewert
false zurückgegeben.Beispiele
Binärdatei aus PostgreSQL Large Object an den Browser streamen
<?php
// Datenbankverbindung herstellen
$conn = pg_connect('host=localhost dbname=mydb user=myuser password=secret');
if (!$conn) {
die('Verbindung fehlgeschlagen');
}
// OID des Large Objects (z. B. aus einer Tabelle gelesen)
$oid = 123456;
// Transaktion starten – Pflicht für Large Objects in PostgreSQL
pg_query($conn, 'BEGIN');
// Large Object im Lese-Modus öffnen
$lob = pg_lo_open($conn, $oid, 'r');
if (!$lob) {
pg_query($conn, 'ROLLBACK');
die('Large Object konnte nicht geöffnet werden');
}
// HTTP-Header für einen PDF-Download setzen
header('Content-Type: application/pdf');
header('Content-Disposition: attachment; filename="dokument.pdf"');
// Ausgabe-Buffer leeren, um keine ungewollten Bytes zu senden
if (ob_get_level()) {
ob_end_clean();
}
// Gesamten Inhalt direkt an den Client senden
$bytes = pg_lo_read_all($lob);
// Large Object schließen und Transaktion beenden
pg_lo_close($lob);
pg_query($conn, 'COMMIT');
echo "<!-- $bytes Bytes wurden gesendet -->";
?>
Bild aus Large Object als Inline-Ressource ausgeben
<?php
$conn = pg_connect('host=localhost dbname=mydb user=myuser password=secret');
// OID aus der Datenbank laden
$result = pg_query($conn, "SELECT bild_oid FROM produkte WHERE id = 42");
$row = pg_fetch_assoc($result);
$oid = (int) $row['bild_oid'];
pg_query($conn, 'BEGIN');
$lob = pg_lo_open($conn, $oid, 'r');
if ($lob) {
header('Content-Type: image/jpeg');
if (ob_get_level()) {
ob_end_clean();
}
pg_lo_read_all($lob);
pg_lo_close($lob);
}
pg_query($conn, 'COMMIT');
pg_close($conn);
?>
// Wichtig · Fallstricke
Transaktion erforderlich: PostgreSQL verlangt, dass alle Large-Object-Operationen innerhalb einer Transaktion stattfinden. Fehlt das BEGIN, schlägt pg_lo_open() fehl.
Output-Buffer beachten: Falls PHP-Output-Buffering aktiv ist (z. B. durch ob_start() oder die php.ini-Einstellung output_buffering), werden die gesendeten Bytes zunächst gepuffert. Für den direkten Download-Stream sollte der Buffer mit ob_end_clean() vorher geleert werden.
Speicherverbrauch: Da pg_lo_read_all() den Inhalt nicht in eine PHP-Variable lädt, sondern direkt schreibt, ist es bei sehr großen Dateien deutlich speicherschonender als pg_lo_read() in einer Schleife.
Sicherheit: Die OID des Large Objects sollte niemals direkt aus Benutzereingaben übernommen werden, ohne sie vorher zu validieren, um unautorisierten Zugriff auf fremde Large Objects zu verhindern.