Signatur
Beschreibung
curl_multi_init() erzeugt ein sogenanntes cURL-Multi-Handle, das als Container für mehrere einzelne cURL-Handles dient. Damit lassen sich HTTP-Anfragen (oder andere cURL-Übertragungen) gleichzeitig und nicht-blockierend ausführen, was die Gesamtübertragungszeit erheblich verkürzen kann.
Der typische Ablauf ist: Zuerst werden mit curl_init() einzelne Handles erzeugt und konfiguriert, dann mit curl_multi_add_handle() zum Multi-Handle hinzugefügt. Anschließend wird in einer Schleife curl_multi_exec() aufgerufen, bis alle Übertragungen abgeschlossen sind. Die Ergebnisse lassen sich danach mit curl_multi_getcontent() auslesen.
Seit PHP 8.0 gibt curl_multi_init() ein Objekt vom Typ CurlMultiHandle zurück (zuvor war es eine Ressource). Das Handle muss nach Verwendung mit curl_multi_close() freigegeben werden, um Ressourcenlecks zu vermeiden.
Dieses Muster ist besonders nützlich, wenn man viele externe APIs abfragt, Bilder oder Dateien von mehreren Quellen lädt oder Web-Scraping-Aufgaben mit vielen Zielen erledigt – überall dort, wo serielle Anfragen unnötig Zeit kosten würden.
Rückgabewert
CurlMultiHandle-Objekt zurück (vor PHP 8.0: eine Ressource vom Typ curl_multi), das als Container für parallele cURL-Übertragungen dient.Beispiele
Zwei HTTP-Anfragen parallel ausführen
<?php
// Einzelne cURL-Handles erstellen und konfigurieren
$ch1 = curl_init('https://httpbin.org/get?id=1');
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
$ch2 = curl_init('https://httpbin.org/get?id=2');
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
// Multi-Handle erzeugen
$mh = curl_multi_init();
// Einzelne Handles hinzufügen
curl_multi_add_handle($mh, $ch1);
curl_multi_add_handle($mh, $ch2);
// Übertragungen starten und warten, bis alle abgeschlossen sind
$running = null;
do {
$status = curl_multi_exec($mh, $running);
if ($running) {
curl_multi_select($mh);
}
} while ($running > 0);
// Ergebnisse auslesen
$response1 = curl_multi_getcontent($ch1);
$response2 = curl_multi_getcontent($ch2);
echo "Antwort 1: " . substr($response1, 0, 50) . PHP_EOL;
echo "Antwort 2: " . substr($response2, 0, 50) . PHP_EOL;
// Aufräumen
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_close($ch1);
curl_close($ch2);
curl_multi_close($mh);
Parallele Anfragen an mehrere URLs mit Array-Verwaltung
<?php
$urls = [
'https://httpbin.org/get?page=1',
'https://httpbin.org/get?page=2',
'https://httpbin.org/get?page=3',
];
$mh = curl_multi_init();
$handles = [];
// Alle Handles erstellen und zum Multi-Handle hinzufügen
foreach ($urls as $i => $url) {
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);
curl_multi_add_handle($mh, $ch);
$handles[$i] = $ch;
}
// Alle Übertragungen ausführen
$running = null;
do {
$status = curl_multi_exec($mh, $running);
if ($running) {
curl_multi_select($mh);
}
} while ($running > 0);
// Ergebnisse sammeln und ausgeben
foreach ($handles as $i => $ch) {
$error = curl_error($ch);
if ($error) {
echo "Fehler bei URL $i: $error" . PHP_EOL;
} else {
$content = curl_multi_getcontent($ch);
echo "URL $i — Länge der Antwort: " . strlen($content) . " Bytes" . PHP_EOL;
}
curl_multi_remove_handle($mh, $ch);
curl_close($ch);
}
curl_multi_close($mh);
// Wichtig · Fallstricke
Ressourcenverwaltung: Das Multi-Handle sowie alle einzelnen cURL-Handles müssen nach der Verwendung explizit mit curl_multi_close() bzw. curl_close() freigegeben werden. Andernfalls können Ressourcenlecks entstehen, besonders in lang laufenden Prozessen.
Fehlerbehandlung: curl_multi_exec() gibt einen cURL-Fehlercode zurück. Prüfe nach Abschluss der Schleife jeden einzelnen Handle mit curl_error() und curl_getinfo(), um HTTP-Fehler oder Verbindungsprobleme zu erkennen.
Parallelität vs. Threads: cURL-Multi ist kein echtes Multithreading – es arbeitet mit einem I/O-Multiplexing-Modell. Für CPU-intensive Aufgaben ist es nicht geeignet, für netzwerkgebundene Anfragen ist es jedoch sehr effizient.
PHP-Versionen: Seit PHP 8.0 ist der Rückgabetyp CurlMultiHandle statt einer generischen Ressource. Code, der auf den Ressourcentyp prüft (z. B. is_resource()), muss für PHP 8+ angepasst werden.