W3docs

PHP mysqli_poll() Funktion

PHP mysqli_poll() Funktion: Syntax, Parameter, Rückgabewerte und asynchrone MySQL-Verbindungen mit einem vollständigen Beispiel abfragen.

Die Funktion mysqli_poll() ermöglicht es, mehrere MySQL-Verbindungen gleichzeitig zu überwachen und herauszufinden, welche davon eine asynchrone Abfrage abgeschlossen haben. Sie ist die Brücke zwischen dem Absenden nicht-blockierender Abfragen und dem Abrufen ihrer Ergebnisse, ohne das gesamte Skript auf die langsamste Verbindung warten zu lassen.

Was mysqli_poll() macht

Wenn eine Abfrage auf normalem Weg ausgeführt wird, hält PHP an und wartet, bis MySQL antwortet. Bei asynchronen Abfragen (gestartet mit dem Flag MYSQLI_ASYNC) wird die Abfrage gesendet, das Skript läuft aber weiter. Das Problem dabei ist: Wie erkenne ich, wann ein Ergebnis abholbereit ist? Genau das beantwortet mysqli_poll().

Man übergibt ihr eine Liste von Verbindungen, und sie blockiert, bis mindestens eine von ihnen ein Ergebnis bereitstellt (oder bis ein Timeout abläuft). Anschließend teilt sie mit, welche Verbindungen bereit sind, und die Ergebnisse werden mit reap_async_query() abgerufen.

Das ist wichtig, wenn mehrere unabhängige Abfragen parallel ausgeführt werden sollen — zum Beispiel beim Abfragen zweier verschiedener Datenbanken oder beim gleichzeitigen Ausführen mehrerer aufwändiger Berichte. Statt jede Abfrage nacheinander auszuführen, werden alle gleichzeitig gestartet und laufen parallel.

Wichtig: mysqli_poll() funktioniert nur mit dem mysqlnd-Treiber. Mit dem älteren libmysql-Treiber ist sie nicht verfügbar. Außerdem ist sie nur prozedural nutzbar — es gibt keine objektorientierte Methode $mysqli->poll(); sie wird immer als mysqli_poll(...) aufgerufen.

Syntax

mysqli_poll(
    array &$read,
    array &$error,
    array &$reject,
    int $seconds,
    int $microseconds = 0
): int|false

Parameter

ParameterBeschreibung
$readListe der zu prüfenden Verbindungen. Per Referenz übergeben — bei der Rückgabe wird sie auf die Verbindungen reduziert, die ein Ergebnis bereitstellen.
$errorWird auf Verbindungen reduziert, bei denen ein Fehler aufgetreten ist.
$rejectWird auf abgelehnte Verbindungen reduziert (bei denen keine asynchrone Abfrage aussteht).
$secondsMaximale Wartezeit in Sekunden.
$microsecondsZusätzliche Wartezeit in Mikrosekunden (optional, Standard: 0).

Rückgabewert

Gibt bei Erfolg die Anzahl der bereiten Verbindungen zurück, oder false bei einem Fehler. Ein Rückgabewert von 0 bedeutet, dass der Timeout abgelaufen ist, bevor eine Verbindung bereit war — das ist kein Fehler.

Verwendung der mysqli_poll() Funktion

Das Muster besteht immer aus denselben drei Schritten:

  1. Eine Verbindung pro Abfrage öffnen, die parallel ausgeführt werden soll.
  2. Jede Abfrage mit dem Flag MYSQLI_ASYNC starten, damit sie nicht blockiert.
  3. In einer Schleife mysqli_poll() aufrufen, um auf die nächste fertige Verbindung zu warten, und deren Ergebnis abrufen.
<?php
// Open one connection per parallel query.
$conn1 = new mysqli("localhost", "user", "pass", "shop");
$conn2 = new mysqli("localhost", "user", "pass", "shop");

foreach ([$conn1, $conn2] as $c) {
    if ($c->connect_errno) {
        exit("Connect failed: " . $c->connect_error);
    }
}

// Fire both queries asynchronously — neither call blocks.
$conn1->query("SELECT SLEEP(1), 'orders done' AS msg", MYSQLI_ASYNC);
$conn2->query("SELECT SLEEP(2), 'reports done' AS msg", MYSQLI_ASYNC);

$pending = [$conn1, $conn2];

while (!empty($pending)) {
    // Copies that mysqli_poll() will rewrite by reference.
    $read   = $pending;
    $error  = $pending;
    $reject = $pending;

    // Block up to 5 seconds for at least one connection to become ready.
    if (mysqli_poll($read, $error, $reject, 5) === false) {
        echo "Poll failed.\n";
        break;
    }

    // $read now holds only the connections with a result waiting.
    foreach ($read as $conn) {
        if ($result = $conn->reap_async_query()) {
            $row = $result->fetch_assoc();
            echo $row['msg'] . "\n";
            $result->free();
        } else {
            echo "Query error: " . $conn->error . "\n";
        }
        // Remove this connection from the pending list.
        $pending = array_filter($pending, fn($c) => $c !== $conn);
    }
}

$conn1->close();
$conn2->close();
?>

Obwohl die erste Abfrage 1 Sekunde schläft und die zweite 2 Sekunden, wird das gesamte Skript in etwa 2 Sekunden abgeschlossen — nicht in 3 — da beide Abfragen gleichzeitig liefen. Da die 1-Sekunden-Abfrage zuerst fertig ist, lautet die Ausgabe:

orders done
reports done

Was der Code Schritt für Schritt macht

  • Es werden zwei Verbindungen geöffnet, da jede Verbindung nur eine asynchrone Abfrage gleichzeitig ausführen kann.
  • query(..., MYSQLI_ASYNC) sendet jede Abfrage und kehrt sofort zurück, ohne zu warten.
  • Vor jedem mysqli_poll()-Aufruf wird $pending in $read, $error und $reject kopiert, weil die Funktion diese Arrays per Referenz überschreibt. $read enthält danach nur die bereiten Verbindungen, $error die fehlgeschlagenen und $reject die ohne ausstehende Abfrage.
  • Für jede bereite Verbindung wird reap_async_query() aufgerufen, um das Ergebnis zu holen, und die Verbindung wird aus $pending entfernt, damit sie nicht erneut abgefragt wird.
  • Die Schleife endet, sobald alle Abfragen abgerufen wurden.

Hinweis: Für komplexe asynchrone Arbeitslasten empfehlen sich Event-Loop-Bibliotheken wie ReactPHP oder Swoole, die robustere Architekturen bieten als eine manuell erstellte Poll-Schleife.

Verwandte Funktionen

  • reap_async_query() — das Ergebnis einer Verbindung abrufen, die mysqli_poll() als bereit gemeldet hat.
  • query() — eine Abfrage ausführen (mit MYSQLI_ASYNC als nicht-blockierende Variante).
  • multi_query() — mehrere Anweisungen in einem Aufruf auf einer einzigen Verbindung ausführen.
  • connect_errno — prüfen, ob ein Verbindungsversuch fehlgeschlagen ist.

Fazit

mysqli_poll() ist das Stück, das parallele MySQL-Abfragen in PHP praktisch macht: Es wartet auf viele Verbindungen gleichzeitig und teilt mit, welche zum Lesen bereit sind. In Kombination mit MYSQLI_ASYNC-Abfragen und reap_async_query() — und dem Wissen, dass der mysqlnd-Treiber benötigt wird — lässt sich die Gesamtzeit mehrerer unabhängiger Abfragen auf etwa die Dauer der langsamsten reduzieren.

Übungen

Übung
Welche Aussagen über die PHP-Funktion mysqli_poll() sind korrekt?
Welche Aussagen über die PHP-Funktion mysqli_poll() sind korrekt?
Was this page helpful?