Start · Sprachen · PHP · Referenz · pg_socket_poll

pg_socket_poll

Funktion

Prüft das zugrunde liegende Socket einer PostgreSQL-Verbindung auf Lese- und/oder Schreibbereitschaft innerhalb eines definierten Timeouts.

seit PHP 8.3.0 Kategorie: db

Signatur

pg_socket_poll(PgSql\Connection $connection, int $seconds, int $microseconds): int

Beschreibung

pg_socket_poll() wartet auf einem PostgreSQL-Verbindungs-Socket, bis dieses entweder zum Lesen oder zum Schreiben bereit ist, oder bis das angegebene Timeout abläuft. Die Funktion ist besonders nützlich bei nicht-blockierenden Datenbankoperationen, bei denen man explizit prüfen möchte, ob ein Socket bereit ist, bevor man asynchrone Abfragen absendet oder Ergebnisse abruft.

Im Zusammenspiel mit pg_send_query(), pg_get_result() und pg_connection_busy() ermöglicht die Funktion vollständig nicht-blockierende PostgreSQL-Kommunikation. Statt aktiv in einer Schleife zu pollen, kann man mit pg_socket_poll() effizient auf Ereignisse warten, ohne CPU unnötig zu belasten.

Das Timeout wird in Sekunden ($seconds) und Mikrosekunden ($microseconds) angegeben. Ein Timeout von 0, 0 führt zu einer sofortigen Rückkehr (non-blocking check), während negative Werte ein unbegrenztes Warten bedeuten.

Der Rückgabewert gibt an, ob das Socket bereit zum Lesen (1), zum Schreiben (2), zu beidem (3) ist, im Timeout gelaufen ist (0) oder ein Fehler aufgetreten ist (-1).

Parameter

Name Typ Default Beschreibung
$connection Pflicht PgSql\Connection Eine aktive PostgreSQL-Verbindungsinstanz, wie sie von pg_connect() oder pg_pconnect() zurückgegeben wird.
$seconds Pflicht int Maximale Wartezeit in Sekunden. Ein negativer Wert bedeutet unbegrenztes Warten. In Kombination mit $microseconds ergibt sich das gesamte Timeout.
$microseconds Pflicht int Zusätzlicher Timeout-Anteil in Mikrosekunden. Wird zu $seconds addiert, um das Gesamt-Timeout zu bilden.

Rückgabewert

Typ
int
Beschreibung

Gibt einen Integer zurück, der den Zustand des Sockets beschreibt:

  • -1: Ein Fehler ist aufgetreten.
  • 0: Das Timeout ist abgelaufen, ohne dass das Socket bereit war.
  • 1: Das Socket ist zum Lesen bereit.
  • 2: Das Socket ist zum Schreiben bereit.
  • 3: Das Socket ist sowohl zum Lesen als auch zum Schreiben bereit.

Beispiele

Nicht-blockierende Abfrage mit Socket-Poll

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

// Asynchrone Abfrage absenden
if (!pg_send_query($conn, 'SELECT pg_sleep(1), 42 AS answer')) {
    die('Abfrage konnte nicht gesendet werden: ' . pg_last_error($conn));
}

// Warte bis zu 5 Sekunden auf Ergebnis
$status = pg_socket_poll($conn, 5, 0);

if ($status === -1) {
    echo 'Fehler beim Polling des Sockets.' . PHP_EOL;
} elseif ($status === 0) {
    echo 'Timeout: Kein Ergebnis innerhalb von 5 Sekunden.' . PHP_EOL;
} else {
    // Socket ist bereit, Ergebnis abrufen
    $result = pg_get_result($conn);
    if ($result) {
        $row = pg_fetch_assoc($result);
        echo 'Antwort: ' . $row['answer'] . PHP_EOL;
    }
}

pg_close($conn);
Antwort: 42

Sofort-Prüfung ohne Warten (Non-blocking Check)

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

pg_send_query($conn, 'SELECT NOW()');

// Sofortiger Check: Timeout 0,0
$status = pg_socket_poll($conn, 0, 0);

switch ($status) {
    case -1:
        echo 'Socket-Fehler.' . PHP_EOL;
        break;
    case 0:
        echo 'Socket noch nicht bereit.' . PHP_EOL;
        break;
    case 1:
    case 3:
        $result = pg_get_result($conn);
        if ($result && !pg_result_error($result)) {
            $row = pg_fetch_row($result);
            echo 'Aktuelle Zeit: ' . $row[0] . PHP_EOL;
        }
        break;
}

pg_close($conn);
Aktuelle Zeit: 2024-05-01 12:00:00.123456+00

// Wichtig · Fallstricke

Verfügbarkeit: pg_socket_poll() ist erst ab PHP 8.3.0 verfügbar und erfordert libpq mit entsprechender Unterstützung. In älteren PHP-Versionen kann man stream_select() in Kombination mit dem von pg_socket() gelieferten Socket-Handle als Alternative nutzen.

Nicht-blockierende Nutzung: Vergessen Sie nicht, die Verbindung zuerst über pg_send_query() o.ä. in den asynchronen Modus zu versetzen. Bei synchronen Verbindungen ist der Einsatz von pg_socket_poll() nicht sinnvoll.

Rückgabewert prüfen: Prüfen Sie immer explizit auf -1 (Fehler) und 0 (Timeout), um Folgefehler beim Datenabruf zu vermeiden.