PHP 本身不支援原生多執行緒,但透過 cURL Multi 介面 可實現並發非阻塞請求,大幅提升爬蟲、API 聚合等場景的吞吐量。本文提供兩種完整實作範例:直接寫入檔案與先存變數再處理。
curl_multi_init():建立多執行緒控制代碼curl_multi_add_handle():將單一 cURL handle 加入多執行緒批次curl_multi_exec():執行批次請求,需在迴圈中反覆呼叫直到所有完成curl_multi_getcontent():取得個別請求的回應內容適合大量資料直接落地存儲,記憶體佔用極低。
<?php
$urls = array(
'https://www.sina.com.cn/',
'https://www.sohu.com/',
'https://www.163.com/'
);
$save_to = '/test.txt';
$fp = fopen($save_to, "a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER, 0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($conn[$i], CURLOPT_FILE, $fp); // 直接寫入檔案指標
curl_multi_add_handle($mh, $conn[$i]);
}
$active = null;
do {
curl_multi_exec($mh, $active);
} while ($active);
// 清理資源
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh, $conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($fp);
?>
適合需要對回應資料進行後處理(如解析、過濾、入資料庫)的場景。
<?php
$urls = array(
'https://www.sina.com.cn/',
'https://www.sohu.com/',
'https://www.163.com/'
);
$save_to = '/test.txt';
$fp = fopen($save_to, "a");
$mh = curl_multi_init();
foreach ($urls as $i => $url) {
$conn[$i] = curl_init($url);
curl_setopt($conn[$i], CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0)");
curl_setopt($conn[$i], CURLOPT_HEADER, 0);
curl_setopt($conn[$i], CURLOPT_CONNECTTIMEOUT, 60);
curl_setopt($conn[$i], CURLOPT_RETURNTRANSFER, true); // 關鍵:回傳字串而非直接輸出
curl_multi_add_handle($mh, $conn[$i]);
}
$active = null;
do {
curl_multi_exec($mh, $active);
} while ($active);
// 取得各請求結果並處理
foreach ($urls as $i => $url) {
$data = curl_multi_getcontent($conn[$i]);
fwrite($fp, $data); // 這裡可改為 DB 寫入、JSON 解析等
}
// 清理
foreach ($urls as $i => $url) {
curl_multi_remove_handle($mh, $conn[$i]);
curl_close($conn[$i]);
}
curl_multi_close($mh);
fclose($fp);
?>
curl_error() 檢查個別 handle 錯誤,配合 curl_multi_info_read() 獲取完成請求的詳細資訊。CURLOPT_CONNECTTIMEOUT 與 CURLOPT_TIMEOUT,防止殭屍連線佔用資源。掌握 cURL Multi,讓 PHP 也能輕鬆應對高併發網路請求場景。