欧美一区二区三区,国内熟女精品熟女A片视频小说,日本av网,小鲜肉男男GAY做受XXX网站

php curl多線程

趙雅婷1年前8瀏覽0評論

最近在開發一個需要大量獲取網絡數據的項目,于是就接觸了php curl的多線程編程。多線程編程在提高效率方面有很明顯的優勢,不過想要用好curl多線程,還需要了解一些相關的基礎知識和技巧。

首先來看curl_multi_init()和 curl_multi_add_handle()這兩個函數。下面是一個簡單的例子:

<?php
$mh = curl_multi_init();
$ch1 = curl_init("http://www.example.com/");
$ch2 = curl_init("http://www.example.net/");
curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);
do {
$status = curl_multi_exec($mh, $active);
if ($active) {
curl_multi_select($mh);
}
} while ($active && $status == CURLM_OK);
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);
?>

這個例子中,我們使用了 curl_multi_init() 函數來初始化一個 multi-handle(多個curl句柄的句柄),并使用 curl_multi_add_handle() 把多個 curl 句柄添加到 multi-handle 中。然后使用curl_multi_exec()函數執行多個 curl 句柄。需要注意的是,curl_multi_exec() 函數并不會阻塞程序的進行,所以我們需要不斷調用這個函數來確保所有 curl 句柄的執行。

關于curl_multi_exec()函數,這里再舉個例子。

<?php
$curl_handles = array($ch1, $ch2, $ch3); // 初始化curl句柄
$mh = curl_multi_init(); // 初始化多句柄
foreach ($curl_handles as $ch) {
curl_multi_add_handle($mh, $ch);
}
$active = null;
do {
$multi_exec = curl_multi_exec($mh, $active);
} while ($multi_exec == CURLM_CALL_MULTI_PERFORM);
while ($active && $multi_exec == CURLM_OK) {
if (curl_multi_select($mh) == -1) {
usleep(1000);
}
do {
$multi_exec = curl_multi_exec($mh, $active);
} while ($multi_exec == CURLM_CALL_MULTI_PERFORM);
}
foreach ($curl_handles as $ch) {
curl_multi_remove_handle($mh, $ch);
}
curl_multi_close($mh);
?>

這個例子做了兩件事情。一是執行多個 curl 句柄,并等待它們全部結束;二是限制了同時運行的 curl 句柄數量(使用curl_multi_select()函數),來降低對系統的負荷。

當然,這兩個函數并不能滿足我們全部的需求。有些時候,我們還需要調用 curl_multi_info_read() 函數來獲得某些操作的結果并做出相應的處理。舉個例子:

<?php
// 初始化一些curl句柄
$ch1 = curl_init("http://www.example.com/");
$ch2 = curl_init("http://www.example.net/");
$ch3 = curl_init("http://www.example.org/");
$handles = array($ch1, $ch2, $ch3);
// 初始化多個句柄
$mh = curl_multi_init();
foreach ($handles as $handle) {
curl_multi_add_handle($mh, $handle);
}
// 執行curl句柄
$running = null;
do {
curl_multi_exec($mh, $running);
} while ($running != 0);
// 處理結果
while ($info = curl_multi_info_read($mh)) {
$handle = $info['handle'];
$url = curl_getinfo($handle, CURLINFO_EFFECTIVE_URL);
$result = curl_multi_getcontent($handle);
if (preg_match_all('#<title>(.*?)(</title>)?#i', $result, $matches) !== false) {
echo $url . ' - ' . $matches[1][0] . "\n";
}
}
// 關閉多個句柄
foreach ($handles as $handle) {
curl_multi_remove_handle($mh, $handle);
curl_close($handle);
}
curl_multi_close($mh);
?>

這個例子中新增了處理結果的邏輯。使用curl_multi_info_read()函數,我們可以獲得每個 curl 句柄相關的一些信息,如哪個句柄執行結束了、執行的狀態以及錯誤碼等。通過這些信息,我們可以獲得每個句柄的狀態從而進行下一步的處理,如獲取頁面的title等。

除此之外,還需要注意的是:使用curl_multi_init()函數創建的 multi-handle 并不是一個常規的 curl 句柄,所以我們無法通過 curl_setopt() 函數來設置選項。如果需要設置選項,需要在使用curl_multi_add_handle()之前,使用curl_copy_handle()函數來復制一個新的 curl 句柄,再使用 curl_setopt() 來設置相應的選項;完畢后用curl_multi_add_handle()將其添加到 multi-handle 中。

最后要說一點,那就是 php curl 的多線程編程并不是完全無敵的。在某些情況下,它的效率并不是非常高。這時,我們需要考慮使用其他的并發編程方式,如協程、異步IO等。