Start · Sprachen · PHP · Referenz · pg_lo_read_all

pg_lo_read_all

Funktion

Liest ein gesamtes PostgreSQL Large Object und gibt dessen Inhalt direkt an den Browser (Ausgabepuffer) weiter.

seit PHP 4.2.0 Kategorie: db

Signatur

pg_lo_read_all(PgSql\Lob $lob): int

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

Typ
int
Beschreibung
Gibt die Anzahl der an den Ausgabepuffer gesendeten Bytes zurück. Im Fehlerfall wird 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 -->";
?>
(binärer PDF-Inhalt wird direkt an den Browser gestreamt)

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);
?>
(JPEG-Bilddaten werden direkt an den Browser gesendet)

// 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.