PHP中的curl_multi一類函數可以實現同時請求多個url,而不是一個一個依次請求,這就類似一個進程實現了多個線程的功能,因此可以使用PHP利用CURL_MULTI實現完成多線程類的任務,下面就一個利用PHP CURL_MULTI多線程采集網頁為例來說明一下。
01 |
<?php |
02 |
//功能:PHP利用CURL_MULTI多線程采集網頁函數 |
03 |
$text =remote( array ( 'http://www.phpernote.com' , 'http://www.baidu.com/' , 'http://www.google.com.hk/' , 'http://www.taobao.com' )); |
04 |
print_r( $text ); |
05 |
function remote( $urls ){ |
06 |
if (! is_array ( $urls )||! count ( $urls )){ |
07 |
return false; |
08 |
} |
09 |
$curl = $text = array (); |
10 |
$handle =curl_multi_init(); |
11 |
foreach ( $urls as $k => $v ){ |
12 |
//$nurl[$k]=preg_replace('/([^:\/\.]+)/i',rawurlencode('\\1'),$v); |
13 |
//$curl[$k]=curl_init($nurl[$k]); |
14 |
$curl [ $k ]=curl_init( $v ); |
15 |
curl_setopt( $curl [ $k ], CURLOPT_RETURNTRANSFER,1); |
16 |
curl_setopt( $curl [ $k ], CURLOPT_HEADER,0); |
17 |
curl_multi_add_handle( $handle , $curl [ $k ]); |
18 |
} |
19 |
$active = null; |
20 |
do { |
21 |
$mrc =curl_multi_exec( $handle , $active ); |
22 |
} while ( $mrc ==CURLM_CALL_MULTI_PERFORM); |
23 |
while ( $active && $mrc ==CURLM_OK){ |
24 |
if (curl_multi_select( $handle )!=-1){ |
25 |
do { |
26 |
$mrc =curl_multi_exec( $handle , $active ); |
27 |
} while ( $mrc ==CURLM_CALL_MULTI_PERFORM); |
28 |
} |
29 |
} |
30 |
|
31 |
foreach ( $curl as $k => $v ){ |
32 |
if (curl_error( $curl [ $k ])== "" ){ |
33 |
$text [ $k ]=(string)curl_multi_getcontent( $curl [ $k ]); |
34 |
} |
35 |
curl_multi_remove_handle( $handle , $curl [ $k ]); |
36 |
curl_close( $curl [ $k ]); |
37 |
} |
38 |
curl_multi_close( $handle ); |
39 |
return $text ; |
40 |
} |
另外我對CURL_MULTI類的函數也做了一下小小的總結,通過查看php手冊文檔會找出PHP CURL_MULTI類的函數主要有以下幾個:
curl_multi_add_handle
curl_multi_close
curl_multi_exec
curl_multi_getcontent
curl_multi_info_read
curl_multi_init
curl_multi_remove_handle
curl_multi_select
調用這些函數實現目的的步驟一般如下:
第一步:調用curl_multi_init初始化一個curl批處理句柄資源
第二步:循環調用curl_multi_add_handle向curl批處理會話中添加單獨的curl句柄資源(這一步需要注意的是,curl_multi_add_handle的第二個參數是由curl_init而來的子handle)
第三步:持續調用curl_multi_exec解析curl批處理句柄
第四步:根據需要循環調用curl_multi_getcontent返回獲取的輸出的文本流以獲取結果
第五步:調用curl_multi_remove_handle移除curl批處理句柄資源中的某個句柄資源,並為每個handle調用curl_close
第六步:調用curl_multi_close關閉批處理句柄資源
另外需要注意的是PHP 5 版本才可以使用這個函數,必須開啟 curl 擴展(打開 php.ini 把;extension=php_curl.dll前面的分號去掉 , 重啟apache 就可以使用了)。