在Web開發中,如果需要同時向多個服務器發送請求,傳統的方法是使用多線程或者多進程的方式,但是這種方法的缺點是代碼難以維護,而且會帶來大量的資源開銷。
幸運的是,PHP提供了一種更加輕便的并發處理方案——PHP Curl并發。Curl是一種支持多個協議的網絡傳輸庫,而PHP Curl則是基于Curl對PHP進行的封裝,并可以用于對多個URL進行并行處理。
下面我們來看一個簡單的例子,演示如何使用PHP Curl實現并發處理:
$urls = [ 'https://www.google.com', 'https://www.baidu.com', 'https://www.github.com' ]; $multiHandle = curl_multi_init(); $handles = []; foreach ($urls as $url) { $handles[$url] = curl_init($url); curl_setopt($handles[$url], CURLOPT_RETURNTRANSFER, true); curl_multi_add_handle($multiHandle, $handles[$url]); } do { $status = curl_multi_exec($multiHandle, $running); } while ($status === CURLM_CALL_MULTI_PERFORM || $running); foreach ($handles as $url =>$handle) { $html = curl_multi_getcontent($handle); echo "The length of $url is " . strlen($html) . "\n"; curl_multi_remove_handle($multiHandle, $handle); } curl_multi_close($multiHandle);
這段代碼的功能是:并發請求urls數組中的三個URL,然后分別輸出每個頁面的長度。首先使用curl_multi_init()創建一個多個請求的handler,然后遍歷URL數組,對每個URL使用curl_init()創建一個新的handler,并使用curl_setopt()設置選項,比如禁止自動輸出結果,然后使用curl_multi_add_handle()將handler添加到多個請求的handler中。接下來進入一個循環,通過curl_multi_exec()函數執行所有請求,返回值$status表明請求狀態,$running標識請求是否仍在運行。最后遍歷每個handler,使用curl_multi_getcontent()獲取返回結果,處理完畢后使用curl_multi_remove_handle()將handler從多個請求handler中刪除,最后使用curl_multi_close()關閉所有請求handler。
上面的代碼中,我們只是簡單地獲取了每個URL頁面的長度,但是如果我們需要獲取頁面的HTML內容呢?這時候我們需要使用另一個函數curl_multi_select(),它可以等待多個Curl句柄執行完畢并檢查是否存在可讀取的數據。
$active = null; do { $status = curl_multi_exec($multiHandle, $active); curl_multi_select($multiHandle); } while ($status === CURLM_OK && $active);
新增的代碼使用do-while循環和curl_multi_select()函數,不斷執行請求并等待返回結果,直到所有請求都處理完畢。這樣就可以保證在每個handler的狀態都發生改變時再進入下一次循環,避免一次請求沒有處理完就開始下一次請求的情況。
除了上述方法外,PHP Curl還有許多高級用法,比如進程池處理、延時請求等。總之,使用PHP Curl并發可以大大提高代碼效率,減輕服務器負擔,是Web開發中不可或缺的一部分。