Einleitung: Warum sollten PHP-Entwickler über Concurrency nachdenken?
\n\nFrüher galt PHP als Sprache für „schnelle Skripte“, bei denen alles sequenziell abläuft und keine ernsthafte Parallelarbeit nötig ist. Die Zeiten haben sich geändert. Heute bauen wir mit PHP hochbelastbare APIs, Aufgabenwarteschlangen, WebSockets und sogar Microservices. Da stellt sich die Frage: Wie bringt man PHP dazu, mehrere Dinge gleichzeitig zu erledigen, ohne alles zu blockieren?
\n\nIn diesem Artikel betrachten wir drei Ansätze für Concurrency in PHP: klassische Threads (pthreads), leichte Goroutinen (Fiber) und die moderne async/await-Syntax. Sie sehen echte Codebeispiele, erfahren, welches Werkzeug wann sinnvoll ist und was Sie 2025 wählen sollten.
\n\nWenn Sie nach paralleler Ausführung in PHP für die Datenverarbeitung suchen oder verstehen möchten, wie sich PHP-Goroutinen von Threads unterscheiden – sind Sie hier genau richtig.
\n\n1. Multithreading in PHP: pthreads – alt, aber mächtig
\n\nWas ist das und wie funktioniert es?
\npthreads ist eine Erweiterung, die PHP die Möglichkeit gibt, echte OS-Threads zu erstellen. Jeder Thread ist eine separate Instanz der Zend Engine mit eigenem Speicher, aber mit der Möglichkeit, Daten über Threaded-Objekte auszutauschen.
Wichtiger Hinweis: pthreads funktioniert nur im CLI-Modus und wird in der Web-Umgebung (Apache/Nginx mod_php) nicht unterstützt. Dafür ist es die einzige Möglichkeit, echte Parallelität (nicht nur Concurrency) auf CPU-Ebene zu erreichen.
\n\nBeispiel: Paralleles Abrufen von URLs
\n<?php\n// Stellen Sie sicher, dass die pthreads-Erweiterung installiert ist\nclass UrlFetcher extends Thread {\n private $url;\n private $result;\n\n public function __construct(string $url) {\n $this->url = $url;\n }\n\n public function run() {\n // Wird in einem separaten Thread ausgeführt\n $this->result = file_get_contents($this->url);\n }\n\n public function getResult() {\n return $this->result;\n }\n}\n\n$urls = ['https://api.example.com/1', 'https://api.example.com/2', 'https://api.example.com/3'];\n$threads = [];\n\nforeach ($urls as $url) {\n $thread = new UrlFetcher($url);\n $thread->start(); // Thread starten\n $threads[] = $thread;\n}\n\n// Ergebnisse sammeln\nforeach ($threads as $thread) {\n $thread->join(); // Auf Abschluss warten\n echo $thread->getResult() . PHP_EOL;\n}\n?>\n\nDer Code startet drei Threads, die jeweils ihre eigene URL abrufen. Die Ausführungszeit entspricht in etwa der des langsamsten Requests, nicht der Summe aller drei. Eine hervorragende Veranschaulichung von paralleler Ausführung in PHP.
\n\nWann sollte man pthreads verwenden?
\n- \n
- Schwere CPU-Aufgaben (Bildverarbeitung, Verschlüsselung, PDF-Rendering). \n
- Parsen großer Datenmengen in CLI-Skripten. \n
- Wenn echte Parallelität und keine kooperative Multitasking benötigt wird. \n
2. Goroutinen in PHP: Fiber – leicht und kontrolliert
\n\nWas ist Fiber?
\nSeit PHP 8.1 gibt es Fiber – das Äquivalent zu Goroutinen in Go oder Coroutinen in Python. Im Gegensatz zu Threads erzeugt Fiber keinen separaten OS-Prozess. Es ist eine leichte Ausführungseinheit, die in einem einzigen Thread läuft und auf Anweisung des Entwicklers umschaltet.
\n\nDie Kernidee: Sie entscheiden selbst, wann der aktuelle Fiber pausiert und die Kontrolle an einen anderen übergibt. Dies wird als kooperatives Multitasking bezeichnet. Ideal für I/O-Operationen (API-Aufrufe, Dateilesen, Datenbankabfragen).
\n\nBeispiel: Asynchrones Durchsuchen von Verzeichnissen
\n<?php\nfunction readFileAsync(string $path): Fiber {\n return new Fiber(function () use ($path) {\n $handle = fopen($path, 'r');\n $content = '';\n while (!feof($handle)) {\n $chunk = fread($handle, 4096);\n $content .= $chunk;\n // Fiber pausieren, um anderen Fibers eine Chance zu geben