php curl 是一個(gè)功能強(qiáng)大的網(wǎng)絡(luò)請(qǐng)求工具,它可以通過編寫PHP代碼,模擬瀏覽器發(fā)送各種請(qǐng)求,獲取和處理遠(yuǎn)程數(shù)據(jù),為我們的 Web 應(yīng)用提供豐富的數(shù)據(jù)支持。但是,在高并發(fā)的情況下,單一請(qǐng)求量很容易就達(dá)到瓶頸,而且 PHP 默認(rèn)的 curl 執(zhí)行方式是同步阻塞的,這就需要我們考慮使用 curl 隊(duì)列,通過異步方式批量執(zhí)行一系列的 curl 請(qǐng)求,進(jìn)一步提高應(yīng)用的性能穩(wěn)定性。
下面,我們以一個(gè)簡(jiǎn)單的需求,來演示如何使用 curl 隊(duì)列。我們需要從一張圖片的 URL 中獲取圖片數(shù)據(jù),并存儲(chǔ)到本地文件中,然后將本地的圖片路徑存儲(chǔ)到數(shù)據(jù)庫中,最終返回一個(gè) JSON 格式的結(jié)果。
$urls = [ 'http://example.com/img/1.png', 'http://example.com/img/2.png', 'http://example.com/img/3.png', ]; function downloadImage($url) { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $data = curl_exec($ch); curl_close($ch); return $data; } $queue = curl_multi_init(); $handles = []; foreach ($urls as $url) { $handle = curl_init(); curl_setopt($handle, CURLOPT_URL, $url); curl_setopt($handle, CURLOPT_HEADER, false); curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); curl_multi_add_handle($queue, $handle); $handles[] = ['handle' =>$handle, 'url' =>$url]; } $running = null; do { curl_multi_exec($queue, $running); } while ($running >0); foreach ($handles as $handle) { $url = $handle['url']; $content = curl_multi_getcontent($handle['handle']); file_put_contents('path/to/local/' . basename($url), $content); curl_multi_remove_handle($queue, $handle['handle']); } curl_multi_close($queue); $json = json_encode(['status' =>'ok', 'msg' =>'success']); header('Content-type: application/json'); echo $json;
上面的代碼中,我們首先定義了一個(gè)包含三個(gè)圖片 URL 的數(shù)組 $urls。這個(gè)數(shù)組表示了需要下載的圖片列表。
在定義下載函數(shù) downloadImage 中,我們使用 curl_init 創(chuàng)建了一個(gè) cURL 資源,并設(shè)置了該請(qǐng)求的 URL、返回結(jié)果不輸出到瀏覽器、將請(qǐng)求結(jié)果存放在 $data 變量中。最后使用 curl_exec 執(zhí)行請(qǐng)求,并使用 curl_close 關(guān)閉該資源并返回請(qǐng)求結(jié)果。
接下來,我們使用 curl_multi_init 創(chuàng)建了一個(gè)批量請(qǐng)求的隊(duì)列 $queue。然后,我們遍歷 $urls 數(shù)組,為每一個(gè) URL 創(chuàng)建一個(gè) cURL 資源,并設(shè)置該請(qǐng)求的 URL、不輸出響應(yīng)頭、將請(qǐng)求結(jié)果存放在返回的字符串中,并使用 curl_multi_add_handle 將該請(qǐng)求添加到 $queue 中。同時(shí),我們記錄了每個(gè)請(qǐng)求的相關(guān)信息(handle 和 url),方便后續(xù)文件存儲(chǔ)。
下面的 do-while 循環(huán)是 curl_multi_exec 的異步請(qǐng)求執(zhí)行部分,當(dāng) $running 大于 0 時(shí),表示仍有請(qǐng)求在執(zhí)行,隨著每個(gè)請(qǐng)求完成,$running 不斷被修改,知道所有請(qǐng)求都執(zhí)行完畢為止。
最后,我們遍歷每一個(gè)請(qǐng)求的相關(guān)信息,根據(jù) URL 生成本地文件名,并將下載好的圖片數(shù)據(jù)寫入本地文件中。同時(shí),我們使用 curl_multi_remove_handle 從隊(duì)列中移除這個(gè)請(qǐng)求,方便后續(xù)工作。接著,我們使用 curl_multi_close 關(guān)閉隊(duì)列資源。最后,生成一個(gè)成功的 JSON 響應(yīng)內(nèi)容,返回給客戶端。
以上,就是使用 php curl 隊(duì)列的一個(gè)簡(jiǎn)單示例。在實(shí)際的開發(fā)中,我們可以結(jié)合實(shí)際需要,使用更加復(fù)雜的隊(duì)列隊(duì)列實(shí)現(xiàn)異步請(qǐng)求,以提高應(yīng)用性能和可靠性。