Signatur
Beschreibung
mysqli_poll() ist ein zentrales Werkzeug für den asynchronen Datenbankbetrieb in PHP mit MySQLi. Die Funktion wartet auf mehrere Datenbankverbindungen gleichzeitig und meldet, welche davon ein Ergebnis bereithalten, einen Fehler aufweisen oder eine Abfrage abgelehnt haben. Sie wird typischerweise nach dem Absenden asynchroner Abfragen mit MYSQLI_ASYNC eingesetzt.
Die drei Arrays $read, $error und $reject werden beim Aufruf als Eingabelisten übergeben und nach dem Rücksprung so modifiziert, dass sie nur noch die Verbindungen enthalten, auf die das jeweilige Kriterium zutrifft: $read enthält Verbindungen mit verfügbaren Ergebnissen, $error Verbindungen mit aufgetretenen Fehlern und $reject Verbindungen, deren Abfragen abgelehnt wurden.
Das Timeout wird durch $seconds und optional $microseconds gesteuert. Ist das Timeout abgelaufen, ohne dass eine Verbindung bereit wurde, gibt die Funktion 0 zurück. Dies ermöglicht eine nicht-blockierende Schleife über mehrere Verbindungen hinweg und ist besonders nützlich bei der gleichzeitigen Ausführung vieler unabhängiger Datenbankabfragen.
Wichtig: mysqli_poll() erfordert die mysqlnd-Erweiterung (MySQL Native Driver). Sie funktioniert nicht mit der älteren libmysql-Bibliothek.
Parameter
| Name | Typ | Default | Beschreibung |
|---|---|---|---|
| $read Pflicht | array | Liste von mysqli-Verbindungsobjekten, die auf Lesbarkeit (verfügbare Ergebnisse) geprüft werden sollen. Nach dem Aufruf enthält das Array nur noch die Verbindungen, die tatsächlich Daten bereitstellen. |
|
| $error Pflicht | array | Liste von mysqli-Verbindungsobjekten, die auf Fehlerzustände geprüft werden sollen. Nach dem Aufruf enthält das Array nur noch die Verbindungen, bei denen ein Fehler aufgetreten ist. |
|
| $reject Pflicht | array | Liste von mysqli-Verbindungsobjekten, die auf abgelehnte Abfragen geprüft werden sollen. Nach dem Aufruf enthält das Array nur noch die Verbindungen, deren Abfragen zurückgewiesen wurden. |
|
| $seconds Pflicht | int | Maximale Wartezeit in ganzen Sekunden. Zusammen mit $microseconds ergibt sich das gesamte Timeout. Bei 0 kehrt die Funktion sofort zurück (nicht-blockierend). |
|
| $microseconds | int | 0 | Optionaler Anteil des Timeouts in Mikrosekunden, der zum Sekundenanteil addiert wird. |
Rückgabewert
$read, $error und $reject) zurück. Gibt 0 zurück, wenn das Timeout abgelaufen ist, ohne dass eine Verbindung bereit wurde. Gibt false zurück, wenn ein Fehler beim Polling selbst aufgetreten ist (z. B. ungültige Eingabe).Beispiele
Mehrere asynchrone Abfragen parallel ausführen und abfragen
<?php
// Drei separate Datenbankverbindungen erstellen
$conn1 = mysqli_connect('localhost', 'user', 'pass', 'db');
$conn2 = mysqli_connect('localhost', 'user', 'pass', 'db');
$conn3 = mysqli_connect('localhost', 'user', 'pass', 'db');
// Asynchrone Abfragen absenden
mysqli_query($conn1, 'SELECT SLEEP(1)', MYSQLI_ASYNC);
mysqli_query($conn2, 'SELECT COUNT(*) FROM orders', MYSQLI_ASYNC);
mysqli_query($conn3, 'SELECT COUNT(*) FROM users', MYSQLI_ASYNC);
$alle_verbindungen = [$conn1, $conn2, $conn3];
$verbleibend = count($alle_verbindungen);
while ($verbleibend > 0) {
$read = $alle_verbindungen;
$error = $alle_verbindungen;
$reject = $alle_verbindungen;
// Bis zu 5 Sekunden warten, bis mindestens eine Verbindung bereit ist
$bereit = mysqli_poll($read, $error, $reject, 5);
if ($bereit === false) {
echo "Fehler beim Polling!\n";
break;
}
if ($bereit === 0) {
echo "Timeout – keine Verbindung hat geantwortet.\n";
break;
}
// Ergebnisse der bereiten Verbindungen abrufen
foreach ($read as $conn) {
$result = mysqli_reap_async_query($conn);
if ($result) {
$row = mysqli_fetch_row($result);
echo "Ergebnis: " . $row[0] . "\n";
mysqli_free_result($result);
}
$verbleibend--;
}
// Verbindungen mit Fehlern behandeln
foreach ($error as $conn) {
echo "Fehler auf Verbindung: " . mysqli_error($conn) . "\n";
$verbleibend--;
}
// Abgelehnte Verbindungen behandeln
foreach ($reject as $conn) {
echo "Abfrage wurde abgelehnt.\n";
$verbleibend--;
}
}
mysqli_close($conn1);
mysqli_close($conn2);
mysqli_close($conn3);
Nicht-blockierender Poll mit sofortigem Timeout (0 Sekunden)
<?php
$conn = mysqli_connect('localhost', 'user', 'pass', 'db');
mysqli_query($conn, 'SELECT SLEEP(2)', MYSQLI_ASYNC);
$read = [$conn];
$error = [$conn];
$reject = [$conn];
// Sofort zurückkehren ohne zu warten
$bereit = mysqli_poll($read, $error, $reject, 0, 0);
if ($bereit === 0) {
echo "Noch kein Ergebnis verfügbar – Abfrage läuft noch.\n";
} else {
echo "Sofortiger Treffer: " . count($read) . " Verbindung(en) bereit.\n";
}
mysqli_close($conn);
// Wichtig · Fallstricke
Voraussetzung mysqlnd: mysqli_poll() ist ausschließlich verfügbar, wenn PHP mit dem MySQL Native Driver (mysqlnd) kompiliert wurde. Bei Nutzung von libmysql wird ein fataler Fehler ausgelöst. Die Verfügbarkeit lässt sich mit phpinfo() oder php -i | grep mysqlnd prüfen.
Array-Modifikation: Die übergebenen Arrays werden von der Funktion direkt verändert. Es ist daher notwendig, die originale Liste der Verbindungen separat zu halten und die Arrays bei jedem Schleifendurchlauf neu zu befüllen.
Ressourcenverwaltung: Auch wenn eine asynchrone Abfrage einen Fehler erzeugt, muss das Ergebnis mit mysqli_reap_async_query() abgeholt werden, um den internen Verbindungsstatus korrekt zurückzusetzen. Andernfalls können nachfolgende Abfragen auf derselben Verbindung scheitern.
Parallelität: Asynchrone MySQLi-Abfragen laufen nicht in echten Threads, sondern werden über das Netzwerk-I/O-Modell des Betriebssystems multiplexiert. Die tatsächliche Parallelität hängt vom MySQL-Server und der Netzwerklatenz ab.