PHP可控制并发数的异步并发CURL

来源:互联网 发布:人工智能在线观看 编辑:程序博客网 时间:2024/06/10 02:02
参考网址:http://www.onlineaspect.com/2009/01/26/how-to-use-curl_multi-without-blocking/

封装的很好
用起来很方便~
但是注意哦~这个里面有bug,还有一些html需要完善
functionrolling_curl($urls,$callback, $custom_options= null) {

    // make sure therolling window isn't greater than the # of urls
    $rolling_window= 5;
    $rolling_window=(sizeof($urls)<$rolling_window) ?sizeof($urls): $rolling_window;

    $master=curl_multi_init();
    $curl_arr=array();

    // add additional curloptions here
    $std_options=array(CURLOPT_RETURNTRANSFER=>true,
    CURLOPT_FOLLOWLOCATION=>true,
    CURLOPT_MAXREDIRS=>5);
    $options=($custom_options) ?($std_options +$custom_options) :$std_options;

    // start the firstbatch of requests
    for($i =0; $i<$rolling_window;$i++) {
       $ch =curl_init();
      $options[CURLOPT_URL]=$urls[$i];
      curl_setopt_array($ch,$options);
      curl_multi_add_handle($master,$ch);
    }

    do{
      while(($execrun=curl_multi_exec($master,$running)) ==CURLM_CALL_MULTI_PERFORM);
      if($execrun !=CURLM_OK)
          break;
       // a request was just completed -- findout which one
      while($done =curl_multi_info_read($master)){
          $info =curl_getinfo($done['handle']);
          if($info['http_code']== 200) {
              $output=curl_multi_getcontent($done['handle']);

              // request successful. process output using the callbackfunction.
             $callback($output);
//bug在这里,他会有一次空请求
              // start a new request(it's important to do this before removing the oldone)
              $ch=curl_init();
             $options[CURLOPT_URL]=$urls[$i++]; // increment i
             curl_setopt_array($ch,$options);
             curl_multi_add_handle($master,$ch);

              // remove the curlhandle that just completed
             curl_multi_remove_handle($master,$done['handle']);
          } else {
              // request failed. add error handling.
          }
       }
    }while($running);
   
   curl_multi_close($master);
    returntrue;
}