Asynchrone Programmierung in PHP: Vollständiger Leitfaden für Anfänger

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Einführung in die asynchrone Programmierung in PHP

\n\n

Traditionelles PHP arbeitet synchron: Jede Operation wird nacheinander ausgeführt. Wenn ein Skript eine HTTP-Anfrage senden oder eine Datei lesen muss, wartet es auf den Abschluss der Operation und blockiert dabei die Ausführung des gesamten Codes. Für Webanwendungen mit hoher Last wird dies zum Engpass. Asynchrone Programmierung löst dieses Problem, indem sie die gleichzeitige Ausführung mehrerer Aufgaben ohne Blockierung des Hauptthreads ermöglicht.

\n\n

In diesem Leitfaden werden wir untersuchen, wie Asynchronität in PHP funktioniert, welche Werkzeuge verfügbar sind und wie man sie in der Praxis einsetzt. Sie erfahren etwas über Generatoren, die Bibliotheken ReactPHP und Swoole sowie über die neuen Möglichkeiten von PHP 8.1 – Fiber.

\n\n

Grundlagen der asynchronen Programmierung

\n\n

Was ist Asynchronität und warum wird sie benötigt?

\n\n

Stellen Sie sich vor, Sie bereiten das Frühstück zu. Der synchrone Ansatz: Sie stellen den Wasserkocher an, warten, bis das Wasser kocht, und beginnen dann mit dem Braten der Eier. Der asynchrone Ansatz: Sie stellen den Wasserkocher an und bereiten parallel das Rührei zu, während das Wasser erhitzt wird. In PHP bedeutet dies, dass Sie anstatt auf eine Antwort von der Datenbank oder einer externen API zu warten, anderen Code ausführen können.

\n\n

Die wichtigsten Vorteile des asynchronen Ansatzes:

\n
    \n
  • Leistungssteigerung bei I/O-Operationen (Netzwerk, Festplatten, Datenbanken)
  • \n
  • Einsparung von Serverressourcen – weniger Threads verarbeiten mehr Anfragen
  • \n
  • Möglichkeit zur Erstellung von Echtzeitanwendungen (Chats, Benachrichtigungen, Streaming)
  • \n
\n\n

Das Problem des synchronen Codes

\n\n

Betrachten wir ein klassisches Beispiel: das Abrufen von Daten von zwei entfernten APIs. Synchroner Code wird nacheinander ausgeführt:

\n\n
<?php\nfunction fetchData($url) {\n    $ch = curl_init($url);\n    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);\n    $result = curl_exec($ch); // Blockierung während der Anfrage\n    curl_close($ch);\n    return $result;\n}\n\n$start = microtime(true);\n$data1 = fetchData('https://api.example.com/users');\n$data2 = fetchData('https://api.example.com/posts');\necho "Zeit: " . (microtime(true) - $start);\n?>
\n\n

Wenn jede Anfrage 2 Sekunden dauert, beträgt die Gesamtausführungszeit 4 Sekunden, obwohl wir die Anfragen parallel ausführen könnten.

\n\n

Werkzeuge für Asynchronität in PHP

\n\n

1. Generatoren (yield) – leichte Asynchronität

\n\n

Generatoren wurden in PHP 5.5 eingeführt und ermöglichen die Erstellung von Funktionen, die ihre Ausführung anhalten und die Kontrolle an den aufrufenden Code zurückgeben können. Dies ist die Grundlage für die Erstellung von Coroutinen.

\n\n
<?php\nfunction generator() {\n    echo "Start des Generators\\n";\n    yield 1;\n    echo "Nach dem ersten yield\\n";\n    yield 2;\n    echo "Ende\\n";\n}\n\n$gen = generator();\nforeach ($gen as $value) {\n    echo "Erhalten: $value\\n";\n}\n?>
\n\n

Generatoren können verwendet werden, um nicht-blockierende Operationen in Verbindung mit einer Ereignisschleife zu organisieren. Für vollständige Asynchronität reicht dies jedoch nicht aus – eine Bibliothek ist erforderlich.

\n\n

2. ReactPHP – ereignisorientierte Bibliothek

\n\n

ReactPHP ist eine beliebte Bibliothek für asynchrone Programmierung. Sie bietet eine Ereignisschleife (Event Loop), nicht-blockierende Sockets, einen HTTP-Client und -Server. Installation über Composer:

\n\n
composer require react/event-loop react/http
\n\n

Beispiel einer asynchronen HTTP-Anfrage:

\n\n
<?php\nrequire 'vendor/autoload.php';\n\nuse React\\EventLoop\\Factory;\nuse React\\HttpClient\\Client;\nuse React\\HttpClient\\Response;\n\n$loop = Factory::create();\n$client = new Client($loop);\n\n$request = $client->request('GET', 'https://api.example.com/data');\n$request->on('response', function (Response $response) {\n    $response->on('data', function ($chunk) {\n        echo "Fragment erhalten: " . strlen($chunk) . " Bytes\\n";\n    });\n    $response->on('end', function () {\n        echo "Anfrage abgeschlossen\\n";\n    });\n});\n$request->end();\n\necho "Anfrage gesendet, warte...\\n";\n$loop->run();\n?                

Blogs

Buchempfehlungen