php中curl_multi函數集的用法

來源:互聯網
上載者:User
一、引言

這段時間比較忙,已經很久沒有寫部落格了。今天我就來聊聊我關於curl_multi_*函數集的使用心得,關於http請求的問題。

當我們使用者php發起一個http請求的時候。我們會首先想到用什嗎?沒錯,我們會建立curl來請求。當我們在一次執行中需要發起多個http請求呢。這簡單,對每一個URL發起一次url請求。請求玩第1個再請求第2個….這就完了?哪我們還說個啥。

官網連結:http://php.net/manual/zh/book.curl.php

二、多次簡單的curl請求弊端

我們舉個栗子。現在有三個http請求。每個請求耗時2s。如果按照簡單的curl請求(圖1-(1))。耗時6s.這是不能容忍的。如果請求的個數越多耗時約多。

有沒有一種方式來縮小查詢時間?能不能三個http請求同時執行(1-(1))?有很多方法來解決這個問題,將耗時減少到2s。如:多進程、線程、事件迴圈、curl_multi_*等等。最簡單的方式就是通過curl_multi_*函數來完成。事實上curl_multi_*內部實現就是用的事件迴圈。

三、簡單的curl_multi_*運用

/** * * curl_multi_*簡單運用 * * @author: rudy * @date: 2016/07/12 *//** * 根據url,postData擷取curl請求對象,這個比較簡單,可以看官方文檔 */functiongetCurlObject($url,$postData=array(),$header=array()){$options = array();    $url = trim($url);    $options[CURLOPT_URL] = $url;    $options[CURLOPT_TIMEOUT] = 10;    $options[CURLOPT_USERAGENT] = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_10_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/44.0.2403.89 Safari/537.36';    $options[CURLOPT_RETURNTRANSFER] = true;    //    $options[CURLOPT_PROXY] = '127.0.0.1:8888';foreach($headeras$key=>$value){        $options[$key] =$value;    }    if(!empty($postData) && is_array($postData)){        $options[CURLOPT_POST] = true;        $options[CURLOPT_POSTFIELDS] = http_build_query($postData);    }    if(stripos($url,'https') === 0){        $options[CURLOPT_SSL_VERIFYPEER] = false;    }    $ch = curl_init();    curl_setopt_array($ch,$options);    return$ch;}// 建立三個待請求的url對象$chList = array();$chList[] = getCurlObject('https://www.baidu.com');$chList[] = getCurlObject('http://www.jd.com');$chList[] = getCurlObject('http://www.jianshu.com/');// 建立多請求執行對象$downloader = curl_multi_init();// 將三個待請求對象放入下載器中foreach ($chListas$ch){    curl_multi_add_handle($downloader,$ch);}// 輪詢do {    while (($execrun = curl_multi_exec($downloader, $running)) == CURLM_CALL_MULTI_PERFORM) ;    if ($execrun != CURLM_OK) {        break;    }    // 一旦有一個請求完成,找出來,處理,因為curl底層是select,所以最大受限於1024while ($done = curl_multi_info_read($downloader))    {        // 從請求中擷取資訊、內容、錯誤$info = curl_getinfo($done['handle']);        $output = curl_multi_getcontent($done['handle']);        $error = curl_error($done['handle']);        // 將請求結果儲存,我這裡是列印出來print$output;//        print "一個請求下載完成!\n";// 把請求已經完成了得 curl handle 刪除        curl_multi_remove_handle($downloader, $done['handle']);    }    // 當沒有資料的時候進行堵塞,把 CPU 使用權交出來,避免上面 do 死迴圈空跑資料導致 CPU 100%if ($running) {        $rel = curl_multi_select($downloader, 1);        if($rel == -1){            usleep(1000);        }    }    if( $running == false){        break;    }} while (true);// 下載完畢,關閉下載器curl_multi_close($downloader);echo"所有請求下載完成!";

在該例子中,首先建立三個或多個要請求的url請求對象。通過curl_multi_*函數建立下載器。將請求寫入下載器中。最後輪詢。等待三個請求現在完成。做處理。

四、複雜的curl_multi_*運用

這就是curl_multi_*用法?too yong too simple!在上面的例子中。下載器$downloader中的請求是一開始就添加好了的。我們能不能動態向下載器中添加請求。動態從下載器中取出已經完成了的請求。想想。這是什嗎?這不就是爬蟲的核心部分-動態下載器。如何動態添加?我們可以用多進程通過IPC添加。我們可以通過協程通過隊列添加等待。

我這實現了一個通過協程+curl_multi_*的爬蟲架構。
Tspider:https://github.com/hirudy/Tspider。
單進程可處理請求2000-5000/min。

').addClass('pre-numbering').hide(); $(this).addClass('has-numbering').parent().append($numbering); for (i = 1; i <= lines; i++) { $numbering.append($('
  • ').text(i)); }; $numbering.fadeIn(1700); }); });

    以上就介紹了 php中curl_multi函數集的用法,包括了方面的內容,希望對PHP教程有興趣的朋友有所協助。

  • 聯繫我們

    該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

    如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

    A Free Trial That Lets You Build Big!

    Start building with 50+ products and up to 12 months usage for Elastic Compute Service

    • Sales Support

      1 on 1 presale consultation

    • After-Sales Support

      24/7 Technical Support 6 Free Tickets per Quarter Faster Response

    • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.