Start · Sprachen · PHP · Referenz · pg_put_line

pg_put_line

Funktion

Sendet eine NULL-terminierte Zeichenkette direkt an den PostgreSQL-Server, typischerweise für den schnellen Massenimport mit <code>COPY FROM STDIN</code>.

seit PHP 4.0.3 Kategorie: db

Signatur

pg_put_line(PgSql\Connection|string $connection_or_data, string $data = ''): bool

Beschreibung

pg_put_line() überträgt eine Zeichenkette (einschließlich eines abschließenden Null-Bytes) direkt zum verbundenen PostgreSQL-Server. Die Funktion wird fast ausschließlich in Kombination mit dem PostgreSQL-Befehl COPY table FROM STDIN eingesetzt, der einen sehr performanten Massenimport von Daten ermöglicht – deutlich schneller als einzelne INSERT-Statements.

Der typische Ablauf ist: Zunächst wird mit pg_query() der COPY-Befehl abgesetzt, dann werden die Datensätze zeilenweise mit pg_put_line() übertragen. Jede Zeile muss mit einem Zeilenumbruch (\n) enden und mit der Datenübertragungsabschlussmarkierung \. (Backslash-Punkt) plus Zeilenumbruch beendet werden. Zum Abschluss muss zwingend pg_end_copy() aufgerufen werden, um die Transaktion zu synchronisieren.

Wird als erstes Argument eine Verbindungsressource übergeben, bezieht sich die Übertragung auf diese spezifische Verbindung. Fehlt das Verbindungsargument, nutzt PHP die zuletzt geöffnete PostgreSQL-Verbindung. Seit PHP 8.1 wurde der Typ des Verbindungsparameters von resource auf PgSql\Connection geändert.

Wichtig: Daten, die über pg_put_line() gesendet werden, müssen manuell escaped werden, da die Funktion keinerlei automatische Escape-Mechanismen bietet. Fehler beim Escaping können zu Datenverlust oder inkonsistenten Datenbankzuständen führen.

Parameter

Name Typ Default Beschreibung
$connection_or_data Pflicht PgSql\Connection|string Entweder eine PostgreSQL-Datenbankverbindung (PgSql\Connection) oder, wenn kein Verbindungsparameter gewünscht ist, direkt die zu sendende Zeichenkette (dann wird die zuletzt geöffnete Verbindung genutzt).
$data string Die zu sendende Zeichenkette. Wird nur ausgewertet, wenn als erstes Argument eine Verbindung übergeben wurde. Jede Zeile sollte mit \n enden; die letzte Übertragung muss \.\n sein.

Rückgabewert

Typ
bool
Beschreibung
Gibt true bei Erfolg zurück, false bei einem Fehler (z. B. wenn keine gültige Verbindung besteht oder die Übertragung fehlschlägt).

Beispiele

Massenimport mit COPY FROM STDIN

<?php
$conn = pg_connect('host=localhost dbname=testdb user=postgres password=geheim');
if (!$conn) {
    die('Verbindung fehlgeschlagen');
}

// Tabelle vorbereiten (vereinfacht)
// CREATE TABLE produkte (id INT, name TEXT, preis NUMERIC);

$result = pg_query($conn, 'COPY produkte FROM STDIN');
if (!$result) {
    die('COPY-Befehl fehlgeschlagen: ' . pg_last_error($conn));
}

$datensaetze = [
    [1, 'Apfel',  0.99],
    [2, 'Banane', 1.49],
    [3, 'Kirsche', 2.99],
];

foreach ($datensaetze as $zeile) {
    // Felder durch Tab trennen, Zeile mit Newline abschließen
    $linie = implode("\t", $zeile) . "\n";
    pg_put_line($conn, $linie);
}

// Datenübertragung beenden
pg_put_line($conn, "\.\n");
pg_end_copy($conn);

echo 'Import erfolgreich abgeschlossen.' . PHP_EOL;

pg_close($conn);
Import erfolgreich abgeschlossen.

NULL-Werte und Sonderzeichen korrekt übermitteln

<?php
$conn = pg_connect('host=localhost dbname=testdb user=postgres password=geheim');
if (!$conn) {
    die('Verbindung fehlgeschlagen');
}

// CREATE TABLE personen (id INT, vorname TEXT, nachname TEXT, alter INT);

pg_query($conn, 'COPY personen FROM STDIN');

$personen = [
    ['id' => 1, 'vorname' => 'Max',  'nachname' => 'Müller', 'alter' => 30],
    ['id' => 2, 'vorname' => 'Anna', 'nachname' => NULL,     'alter' => 25],
];

foreach ($personen as $p) {
    // NULL-Werte als \N darstellen (PostgreSQL-COPY-Konvention)
    $felder = array_map(function($wert) {
        if ($wert === null) {
            return '\\N'; // NULL-Platzhalter für COPY
        }
        // Tabs und Newlines im Wert escapen
        return str_replace(["\t", "\n", "\\"], ["\\t", "\\n", "\\\\"], (string)$wert);
    }, $p);

    pg_put_line($conn, implode("\t", $felder) . "\n");
}

pg_put_line($conn, "\.\n");
pg_end_copy($conn);

echo 'Personen importiert.' . PHP_EOL;
pg_close($conn);
Personen importiert.

// Wichtig · Fallstricke

Sicherheit: pg_put_line() führt kein automatisches Escaping durch. Sonderzeichen wie Tabs (\t), Zeilenumbrüche (\n) und Backslashes (\) innerhalb der Datenwerte müssen manuell escaped werden, da sie sonst das COPY-Protokoll stören und zu korrupten Datensätzen oder Fehlern führen können.

Pflichtabschluss: Nach der letzten Zeile muss unbedingt pg_put_line($conn, "\.\n") gefolgt von pg_end_copy() aufgerufen werden. Wird pg_end_copy() vergessen, bleibt die Verbindung in einem undefinierten Zustand und weitere Datenbankoperationen schlagen fehl.

Fehlerbehandlung: Bei einem Fehler während der Übertragung sollte die Verbindung geschlossen und neu aufgebaut werden, da eine laufende COPY-Sitzung nicht einfach abgebrochen werden kann, ohne die Verbindung zu korrumpieren.

Alternative: Für komplexere Anforderungen oder wenn Escaping automatisch erledigt werden soll, bietet sich pg_copy_from() an, das ein PHP-Array direkt in eine Tabelle kopiert.