- 論壇徽章:
- 0
|
PHP在多線程還是用得到, 例如要同時連結(jié)不同資料庫的資料表, 運算後取得結(jié)果,
並把這些結(jié)果顯示在頁面上, 如果一個個連線, 運算後得到結(jié)果, 再連線到另一個資料庫,
那可能要等待一段時間, USER就會覺得怎麼那麼慢...
尤其是像跨國公司, 如果他要同時A公司的資料庫, B公司的資料庫, C公司的資料庫...
然後運算各公司業(yè)績後, 顯示在頁面上做一個比較, 這時就很需要多線程去處理了,
不然你要等到連完A公司的資料庫後取得運算結(jié)果, 再連到B公司的資料庫後取得運算結(jié)果.....
這過程無疑會等待許久, 依程式運算資料量的內(nèi)容, 可能十多秒到數(shù)十秒都有可能...
多線程同時連線去處理, 只需要等待處理較久的那個線程即可, 縮短不少時間
以下是一個多線程函數(shù),使用PHP的CURL函數(shù),多線程抓取資料,
亦即程式模仿USER去瀏覽網(wǎng)頁一樣,差別在於因為不是瀏覽器,
所以$_SESSION $_COOKIE等變數(shù)是不存在的.... 要特別注意,
另外要注意是CURL是抓資料,不是執(zhí)行內(nèi)部函數(shù),所以如果你是要抓取你自己的程式執(zhí)行結(jié)果,
你要返回內(nèi)容,必須在該程式內(nèi)使用echo指令輸出,而不是 return,
如果你是返回陣列,先用serialize轉(zhuǎn)為字串輸出,接收之後再用unserialize轉(zhuǎn)為變數(shù)-
- function curl_get_url($url_array, $wait_usec = 0)
- {
- if (!is_array($url_array))
- return false;
- $wait_usec = intval($wait_usec);
- $data = array();
- $handle = array();
- $running = 0;
- $mh = curl_multi_init(); // multi curl handler
- $i = 0;
- foreach($url_array as $url) {
- $ch = curl_init();
- curl_setopt($ch, CURLOPT_URL, $url);
- curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // return don't print
- curl_setopt($ch, CURLOPT_TIMEOUT, 30);
- curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
- curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); // 302 redirect
- curl_setopt($ch, CURLOPT_MAXREDIRS, 7);
- curl_multi_add_handle($mh, $ch); // 把 curl resource 放進 multi curl handler 裡
- $handle[$i++] = $ch;
- }
- /* 執(zhí)行 */
- /* 此種做法會造成 CPU loading 過重 (CPU 100%)
- do {
- curl_multi_exec($mh, $running);
- if ($wait_usec > 0) // 每個 connect 要間隔多久
- usleep($wait_usec); // 250000 = 0.25 sec
- } while ($running > 0);
- */
- /* 此做法就可以避免掉 CPU loading 100% 的問題 */
- // 參考自: http://www.hengss.com/xueyuan/sort0362/php/info-36963.html
- do {
- $mrc = curl_multi_exec($mh, $active);
- } while ($mrc == CURLM_CALL_MULTI_PERFORM);
- while ($active and $mrc == CURLM_OK) {
- if (curl_multi_select($mh) != -1) {
- do {
- $mrc = curl_multi_exec($mh, $active);
- } while ($mrc == CURLM_CALL_MULTI_PERFORM);
- }
- }
- /* 讀取資料 */
- foreach($handle as $i => $ch) {
- $content = curl_multi_getcontent($ch);
- $data[$i] = (curl_errno($ch) == 0) ? $content : false;
- }
- /* 移除 handle*/
- foreach($handle as $ch) {
- curl_multi_remove_handle($mh, $ch);
- }
- curl_multi_close($mh);
- return $data;
- }
復制代碼 範例A
- $urls = array('http://www.baidu.com/img/baidu_sylogo1.gif',
- 'http://www.baidu.com/img/baidu_sylogo1.gif',
- 'http://www.baidu.com/img/baidu_sylogo1.gif'
- );
- print_r(curl_get_url($urls));
復制代碼 範例B
我上面說過$_SESSION是不存在的...所以要用傳值的方式
- $urls = array('http://www.aaa.com/index.php?act=data1&A=1&B=2&C=3',
- 'http://www.aaa.com/index.php?act=data2&A=1&B=2&C=3',
- 'http://www.aaa.com/index.php?act=data3&A=1&B=2&C=3'
- );
- print_r(curl_get_url($urls));
復制代碼 |
|