Signatur
Beschreibung
pg_end_copy() schließt eine zuvor mit pg_copy_from() oder pg_put_line() gestartete COPY-Operation ab und synchronisiert den PHP-Client mit dem PostgreSQL-Server. Die Funktion muss nach dem letzten pg_put_line()-Aufruf aufgerufen werden, damit der Server weiß, dass alle Daten übertragen wurden und die Transaktion abgeschlossen werden kann.
Das COPY-Protokoll von PostgreSQL erlaubt es, große Datenmengen effizient zeilenweise in eine Tabelle zu laden. Typischerweise sendet man die Daten mit pg_put_line() und beendet den Datenstrom mit der speziellen Abschlusssequenz "\\.
", bevor pg_end_copy() aufgerufen wird. Ohne diesen Aufruf bleibt die Verbindung in einem inkonsistenten Zustand und weitere Abfragen schlagen fehl.
Seit PHP 8.1 wird der Verbindungsparameter als PgSql\Connection-Objekt übergeben; in früheren Versionen war es eine Ressource. Wird kein Verbindungsparameter angegeben, verwendet die Funktion die zuletzt geöffnete PostgreSQL-Verbindung.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $connection | PgSql\Connection | Eine aktive PostgreSQL-Datenbankverbindung. Wird der Parameter weggelassen, wird die zuletzt geöffnete Verbindung verwendet. |
Rückgabewert
true bei Erfolg zurück, false wenn die Synchronisation fehlschlägt, z. B. wenn keine aktive COPY-Operation vorliegt oder die Verbindung unterbrochen wurde.Beispiele
Massendaten per COPY in PostgreSQL einfügen
<?php
$conn = pg_connect('host=localhost dbname=testdb user=postgres password=secret');
if (!$conn) {
die('Verbindung fehlgeschlagen');
}
// COPY-Modus starten
$result = pg_query($conn, 'COPY benutzer (name, email) FROM STDIN');
if (!$result) {
die('COPY konnte nicht gestartet werden: ' . pg_last_error($conn));
}
// Daten zeilenweise senden (Tab-getrennt)
$daten = [
['Max Mustermann', 'max@example.com'],
['Erika Muster', 'erika@example.com'],
['Hans Meier', 'hans@example.com'],
];
foreach ($daten as $zeile) {
pg_put_line($conn, implode("\t", $zeile) . "\n");
}
// COPY-Abschlusssequenz senden
pg_put_line($conn, "\\.\n");
// Verbindung synchronisieren und COPY beenden
if (pg_end_copy($conn)) {
echo 'Daten erfolgreich importiert.' . PHP_EOL;
} else {
echo 'Fehler beim Beenden der COPY-Operation: ' . pg_last_error($conn) . PHP_EOL;
}
pg_close($conn);
?>
Fehlerbehandlung bei fehlender Abschlusssequenz
<?php
$conn = pg_connect('host=localhost dbname=testdb user=postgres password=secret');
pg_query($conn, 'COPY produkte (bezeichnung, preis) FROM STDIN');
pg_put_line($conn, "Apfel\t0.99\n");
pg_put_line($conn, "Banane\t1.29\n");
// Abschlusssequenz nicht vergessen!
pg_put_line($conn, "\\.\n");
if (!pg_end_copy($conn)) {
// Im Fehlerfall: Transaktion zurückrollen
pg_query($conn, 'ROLLBACK');
echo 'COPY fehlgeschlagen, Rollback durchgeführt.' . PHP_EOL;
} else {
echo 'Import abgeschlossen.' . PHP_EOL;
}
pg_close($conn);
?>
// Wichtig · Fallstricke
Wichtig: Vor dem Aufruf von pg_end_copy() muss zwingend die COPY-Abschlusssequenz "\\.
" per pg_put_line() gesendet werden. Fehlt diese Sequenz, kann pg_end_copy() hängen bleiben oder mit einem Fehler abbrechen, da der Server noch auf weitere Daten wartet.
Wird pg_end_copy() nicht aufgerufen, bleibt die Datenbankverbindung in einem unbrauchbaren Zustand. Alle nachfolgenden Abfragen auf dieser Verbindung schlagen fehl, bis die Verbindung neu aufgebaut wird.
Für einfachere Masseneinfügungen ohne manuelles Zeilenmanagement bietet sich pg_copy_from() an, das intern ebenfalls pg_end_copy() aufruft.