Start · Sprachen · PHP · Referenz · mysqli_reap_async_query

mysqli_reap_async_query

Funktion

Ruft das Ergebnis einer asynchronen MySQL-Abfrage ab, die zuvor mit <code>MYSQLI_ASYNC</code> gestartet wurde.

seit PHP 5.3.0 Kategorie: db

Signatur

mysqli_reap_async_query(mysqli $mysql): mysqli_result|bool

Beschreibung

mysqli_reap_async_query() wird verwendet, um das Ergebnis einer asynchronen Datenbankabfrage entgegenzunehmen, nachdem mysqli_poll() signalisiert hat, dass das Ergebnis bereitsteht. Asynchrone Abfragen werden mit mysqli_query() und dem Flag MYSQLI_ASYNC gestartet und ermöglichen es, mehrere Datenbankabfragen parallel auszuführen, ohne auf jede einzelne synchron warten zu müssen.

Der typische Arbeitsablauf lautet: Mehrere Verbindungen starten je eine Abfrage mit MYSQLI_ASYNC, dann wird in einer Schleife mysqli_poll() aufgerufen, um auf fertige Verbindungen zu warten, und schließlich wird für jede fertige Verbindung mysqli_reap_async_query() aufgerufen, um das Ergebnisobjekt abzurufen.

Gibt die Funktion ein mysqli_result-Objekt zurück, enthält die Abfrage Ergebniszeilen (SELECT-artige Abfragen). Bei nicht-ergebnisliefernden Abfragen (INSERT, UPDATE, DELETE) wird true bei Erfolg zurückgegeben. Im Fehlerfall wird false zurückgegeben; der Fehler kann dann über mysqli_error() abgefragt werden.

Achtung: Diese Funktion steht nur mit dem mysqlnd-Treiber (MySQL Native Driver) zur Verfügung. Sie ist nicht verfügbar, wenn PHP mit der libmysqlclient-Bibliothek kompiliert wurde.

Parameter

Name Typ Default Beschreibung
$mysql Pflicht mysqli Die mysqli-Verbindungsinstanz, für die eine asynchrone Abfrage mit MYSQLI_ASYNC gestartet wurde und deren Ergebnis nun abgerufen werden soll.

Rückgabewert

Typ
mysqli_result|bool
Beschreibung
Gibt ein mysqli_result-Objekt zurück, wenn die Abfrage Ergebniszeilen liefert (z. B. SELECT). Bei erfolgreichen, aber nicht ergebnisliefernden Abfragen (z. B. INSERT, UPDATE) wird true zurückgegeben. Im Fehlerfall wird false zurückgegeben.

Beispiele

Mehrere asynchrone Abfragen parallel ausführen und auslesen

<?php
// Drei separate Datenbankverbindungen öffnen
$host   = 'localhost';
$user   = 'root';
$pass   = 'secret';
$dbname = 'testdb';

$conn1 = mysqli_connect($host, $user, $pass, $dbname);
$conn2 = mysqli_connect($host, $user, $pass, $dbname);
$conn3 = mysqli_connect($host, $user, $pass, $dbname);

// Asynchrone Abfragen starten
mysqli_query($conn1, 'SELECT SLEEP(1), 1 AS conn', MYSQLI_ASYNC);
mysqli_query($conn2, 'SELECT SLEEP(2), 2 AS conn', MYSQLI_ASYNC);
mysqli_query($conn3, 'SELECT SLEEP(3), 3 AS conn', MYSQLI_ASYNC);

$links      = [$conn1, $conn2, $conn3];
$processed  = 0;
$total      = count($links);

while ($processed < $total) {
    $read   = $links;
    $error  = $links;
    $reject = $links;

    // Warten, bis mindestens eine Verbindung ein Ergebnis bereitstellt
    $ready = mysqli_poll($read, $error, $reject, 5);

    if ($ready === false) {
        echo "mysqli_poll() ist fehlgeschlagen.\n";
        break;
    }

    // Fertige Verbindungen auslesen
    foreach ($read as $link) {
        $result = mysqli_reap_async_query($link);

        if ($result === false) {
            echo 'Fehler: ' . mysqli_error($link) . "\n";
        } elseif ($result instanceof mysqli_result) {
            $row = mysqli_fetch_assoc($result);
            echo 'Verbindung ' . $row['conn'] . ' hat geantwortet.' . "\n";
            mysqli_free_result($result);
        } else {
            // true: nicht-ergebnisliefernde Abfrage erfolgreich
            echo "Abfrage erfolgreich (kein Ergebnissatz).\n";
        }

        $processed++;
    }
}

mysqli_close($conn1);
mysqli_close($conn2);
mysqli_close($conn3);
Verbindung 1 hat geantwortet. Verbindung 2 hat geantwortet. Verbindung 3 hat geantwortet.

Asynchrones INSERT und Fehlerbehandlung

<?php
$conn = mysqli_connect('localhost', 'root', 'secret', 'testdb');

// Asynchrones INSERT starten
mysqli_query($conn, "INSERT INTO logs (message) VALUES ('async test')", MYSQLI_ASYNC);

$read   = [$conn];
$error  = [$conn];
$reject = [$conn];

$ready = mysqli_poll($read, $error, $reject, 5);

if ($ready && !empty($read)) {
    $result = mysqli_reap_async_query($conn);

    if ($result === true) {
        echo 'INSERT erfolgreich, betroffene Zeilen: ' . mysqli_affected_rows($conn) . "\n";
    } elseif ($result === false) {
        echo 'Fehler beim INSERT: ' . mysqli_error($conn) . "\n";
    }
}

mysqli_close($conn);
INSERT erfolgreich, betroffene Zeilen: 1

// Wichtig · Fallstricke

Nur mit mysqlnd: mysqli_reap_async_query() steht ausschließlich zur Verfügung, wenn PHP den MySQL Native Driver (mysqlnd) verwendet. Bei einer Kompilierung gegen libmysqlclient ist die Funktion nicht vorhanden und führt zu einem fatalen Fehler.

Reihenfolge einhalten: mysqli_reap_async_query() darf nur aufgerufen werden, nachdem mysqli_poll() die betreffende Verbindung als bereit gemeldet hat. Ein vorzeitiger Aufruf kann zu unerwartetem Verhalten oder Blockierungen führen.

Ressourcen freigeben: Wenn die Funktion ein mysqli_result-Objekt zurückgibt, sollte dieses nach der Verwendung mit mysqli_free_result() freigegeben werden, um Speicher freizugeben.

Fehlerbehandlung: Sowohl Verbindungen aus dem $error- als auch dem $reject-Array von mysqli_poll() sollten mit mysqli_reap_async_query() abgearbeitet werden, um die Verbindung in einen sauberen Zustand zurückzuversetzen.