Start · Sprachen · PHP · Referenz · pg_connect_poll

pg_connect_poll

Funktion

Prüft den Status eines laufenden asynchronen PostgreSQL-Verbindungsversuchs und gibt einen der <code>PGSQL_POLLING_*</code>-Statuscodes zurück.

seit PHP 8.1.0 Kategorie: db

Signatur

pg_connect_poll(PgSql\Connection $connection): int

Beschreibung

pg_connect_poll() wird zusammen mit pg_connect() (aufgerufen mit dem Flag PGSQL_CONNECT_ASYNC) verwendet, um den Fortschritt eines nicht-blockierenden Verbindungsaufbaus zu überwachen. Statt auf den Abschluss der Verbindung zu warten, kann das Programm zwischenzeitlich andere Aufgaben erledigen und den Status regelmäßig prüfen.

Die Funktion gibt einen Integer-Statuscode zurück, der anzeigt, ob die Verbindung noch aussteht, ob sie auf lesbare oder schreibbare Daten wartet oder ob sie erfolgreich aufgebaut wurde bzw. fehlgeschlagen ist. Typische Werte sind PGSQL_POLLING_READING, PGSQL_POLLING_WRITING, PGSQL_POLLING_OK, PGSQL_POLLING_FAILED und PGSQL_POLLING_ACTIVE.

Dieses Muster ist besonders in Event-Loop-basierten Architekturen oder in Situationen nützlich, in denen mehrere Datenbankverbindungen gleichzeitig aufgebaut werden sollen, ohne jeden einzelnen Verbindungsversuch blockierend abzuwarten.

Solange der Rückgabewert weder PGSQL_POLLING_OK (Verbindung erfolgreich) noch PGSQL_POLLING_FAILED (Verbindung fehlgeschlagen) ist, muss die Polling-Schleife fortgesetzt werden.

Parameter

Name Typ Default Beschreibung
$connection Pflicht PgSql\Connection Eine asynchrone PostgreSQL-Verbindungsressource, die zuvor mit pg_connect() unter Verwendung des Flags PGSQL_CONNECT_ASYNC erstellt wurde.

Rückgabewert

Typ
int
Beschreibung
Gibt einen der folgenden Statuscodes zurück: PGSQL_POLLING_READING (warte auf lesbare Daten), PGSQL_POLLING_WRITING (warte auf schreibbare Daten), PGSQL_POLLING_OK (Verbindung erfolgreich hergestellt), PGSQL_POLLING_FAILED (Verbindungsversuch fehlgeschlagen) oder PGSQL_POLLING_ACTIVE (Verbindungsaufbau noch aktiv).

Beispiele

Asynchronen Verbindungsaufbau mit Polling überwachen

<?php
// Asynchrone Verbindung initiieren
$conn = pg_connect('host=localhost dbname=testdb user=postgres password=secret', PGSQL_CONNECT_ASYNC);

if (!$conn) {
    die('Fehler beim Initiieren der asynchronen Verbindung');
}

// Polling-Schleife: Status regelmäßig prüfen
do {
    $status = pg_connect_poll($conn);

    switch ($status) {
        case PGSQL_POLLING_READING:
            echo "Warte auf lesbare Daten...\n";
            // Hier könnten andere Aufgaben erledigt werden
            break;
        case PGSQL_POLLING_WRITING:
            echo "Warte auf schreibbare Daten...\n";
            break;
        case PGSQL_POLLING_ACTIVE:
            echo "Verbindungsaufbau aktiv...\n";
            break;
        case PGSQL_POLLING_OK:
            echo "Verbindung erfolgreich hergestellt!\n";
            break;
        case PGSQL_POLLING_FAILED:
            die("Verbindungsaufbau fehlgeschlagen!\n");
    }

    // Kurz warten, um CPU-Last zu reduzieren
    usleep(1000);
} while ($status !== PGSQL_POLLING_OK && $status !== PGSQL_POLLING_FAILED);

// Verbindung verwenden
$result = pg_query($conn, 'SELECT version()');
echo pg_fetch_result($result, 0, 0) . "\n";

pg_close($conn);
Warte auf schreibbare Daten... Verbindung erfolgreich hergestellt! PostgreSQL 15.2 on x86_64-pc-linux-gnu, ...

Mehrere asynchrone Verbindungen gleichzeitig aufbauen

<?php
$dsns = [
    'host=db1.example.com dbname=app user=postgres',
    'host=db2.example.com dbname=app user=postgres',
];

// Alle Verbindungen asynchron starten
$connections = [];
foreach ($dsns as $dsn) {
    $conn = pg_connect($dsn, PGSQL_CONNECT_ASYNC);
    if ($conn) {
        $connections[] = $conn;
    }
}

// Alle Verbindungen parallel pollen
$pending = count($connections);
while ($pending > 0) {
    foreach ($connections as $key => $conn) {
        $status = pg_connect_poll($conn);
        if ($status === PGSQL_POLLING_OK) {
            echo "Verbindung #{$key} bereit.\n";
            unset($connections[$key]);
            $pending--;
        } elseif ($status === PGSQL_POLLING_FAILED) {
            echo "Verbindung #{$key} fehlgeschlagen.\n";
            unset($connections[$key]);
            $pending--;
        }
    }
    usleep(500);
}

echo "Alle Verbindungen abgeschlossen.\n";
Verbindung #0 bereit. Verbindung #1 bereit. Alle Verbindungen abgeschlossen.

// Wichtig · Fallstricke

Verfügbarkeit: pg_connect_poll() ist als eigene Funktion erst ab PHP 8.1 dokumentiert, setzt aber intern auf die libpq-Funktion PQconnectPoll() auf, die seit deutlich früheren PostgreSQL-Versionen existiert. In älteren PHP-Versionen war das nicht-blockierende Verbinden schwieriger umzusetzen.

Polling-Flag erforderlich: Die Funktion ist nur sinnvoll, wenn die Verbindung mit PGSQL_CONNECT_ASYNC geöffnet wurde. Bei einer synchronen Verbindung ist der Verbindungsaufbau bereits abgeschlossen, bevor pg_connect() zurückkehrt.

Tight-Loop vermeiden: In einer reinen Busy-Wait-Schleife ohne usleep() oder Socket-basiertes Warten kann die CPU-Auslastung sehr hoch werden. In produktiven Anwendungen sollte stream_select() oder ein vergleichbarer Mechanismus genutzt werden, um effizient auf I/O-Ereignisse zu warten.