Signatur
Beschreibung
pg_cancel_query() wird eingesetzt, um eine zuvor mit pg_send_query(), pg_send_query_params() oder pg_send_execute() gestartete asynchrone Abfrage abzubrechen, bevor deren Ergebnis abgerufen wurde. Die Funktion sendet eine Abbruch-Anforderung an den PostgreSQL-Server und wartet auf dessen Bestätigung.
Typische Einsatzszenarien sind lang laufende Abfragen, die aufgrund eines Timeouts oder einer Benutzeraktion nicht mehr benötigt werden. Im Gegensatz zum Schließen der Verbindung ermöglicht pg_cancel_query() das saubere Abbrechen, sodass die Verbindung anschließend weiterverwendet werden kann.
Nach einem erfolgreichen Abbruch sollte mit pg_get_result() das verbleibende Ergebnis-Objekt abgerufen und verworfen werden, um die Verbindung in einen definierten Zustand zu bringen. Die Funktion ist nur im asynchronen Modus sinnvoll; bei synchronen Abfragen hat sie keine Wirkung, da diese blockierend ausgeführt werden.
Wichtig: Ein Rückgabewert von true bedeutet lediglich, dass die Abbruch-Anforderung erfolgreich gesendet wurde — der Server kann die Abfrage unter Umständen dennoch abgeschlossen haben, bevor der Abbruch ankam.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $connection Pflicht | PgSql\Connection | Eine aktive PostgreSQL-Datenbankverbindung, die durch pg_connect() oder pg_pconnect() erstellt wurde. |
Rückgabewert
true zurück, wenn die Abbruch-Anforderung erfolgreich an den Server gesendet wurde, andernfalls false. Ein true garantiert nicht, dass die Abfrage tatsächlich abgebrochen wurde — sie könnte bereits abgeschlossen worden sein.Beispiele
Asynchrone Abfrage abbrechen und Verbindung bereinigen
<?php
$conn = pg_connect('host=localhost dbname=testdb user=postgres password=geheim');
if (!$conn) {
die('Verbindung fehlgeschlagen');
}
// Asynchrone Abfrage starten (z. B. eine lang laufende Analyse)
$sent = pg_send_query($conn, 'SELECT pg_sleep(30)');
if (!$sent) {
die('Senden der Abfrage fehlgeschlagen');
}
// Abfrage abbrechen
if (pg_cancel_query($conn)) {
echo "Abbruch-Anforderung erfolgreich gesendet." . PHP_EOL;
} else {
echo "Abbruch fehlgeschlagen." . PHP_EOL;
}
// Verbindung bereinigen: verbleibendes Ergebnis verwerfen
while ($result = pg_get_result($conn)) {
pg_free_result($result);
}
echo "Verbindung ist wieder einsatzbereit." . PHP_EOL;
pg_close($conn);
Timeout-basierter Abbruch mit pg_connection_busy()
<?php
$conn = pg_connect('host=localhost dbname=testdb user=postgres password=geheim');
if (!$conn) {
die('Verbindung fehlgeschlagen');
}
pg_send_query($conn, 'SELECT count(*) FROM sehr_grosse_tabelle');
$timeout = 5; // Sekunden
$start = time();
while (pg_connection_busy($conn)) {
if ((time() - $start) >= $timeout) {
echo "Timeout erreicht – Abfrage wird abgebrochen." . PHP_EOL;
pg_cancel_query($conn);
break;
}
usleep(100000); // 100 ms warten
}
// Ergebnis holen oder verwerfen
$result = pg_get_result($conn);
if ($result) {
$status = pg_result_status($result);
echo "Ergebnisstatus: " . $status . PHP_EOL;
pg_free_result($result);
}
pg_close($conn);
// Wichtig · Fallstricke
Verbindungszustand: Nach dem Abbruch muss zwingend pg_get_result() aufgerufen werden, bis es false zurückgibt, um die Verbindung sauber zu halten. Andernfalls können nachfolgende Abfragen fehlschlagen oder unerwartete Ergebnisse liefern.
Synchrone Abfragen: Bei synchronen Abfragen (z. B. pg_query()) kann pg_cancel_query() nicht sinnvoll eingesetzt werden, da PHP blockiert, bis die Abfrage abgeschlossen ist.
Race Condition: Da der Abbruch über das Netzwerk gesendet wird, ist es möglich, dass die Abfrage bereits abgeschlossen war, bevor der Abbruch ankam. Das Programm sollte daher immer das Ergebnis prüfen, anstatt nur den Rückgabewert von pg_cancel_query() zu verwenden.