Php ingcurl\u getinfo($info['handle',CURLINFO\u有效url), “curl\u errno”=>curl\u errno($info['handle']), “curl_error”=>curl_error($info

Php ingcurl\u getinfo($info['handle',CURLINFO\u有效url), “curl\u errno”=>curl\u errno($info['handle']), “curl_error”=>curl_error($info,php,curl,Php,Curl,ingcurl\u getinfo($info['handle',CURLINFO\u有效url), “curl\u errno”=>curl\u errno($info['handle']), “curl_error”=>curl_error($info['handle']), “curl_multi_errno”=>curl_multi_errno($mh), “curl_multi_strerror”=>curl_multi_strerror(curl_multi_errno($mh))

ing<计数(工人)){ //一些工作人员已完成下载,请对其进行处理 //回声“处理!”; 打破 }否则{ //还没有工作人员完成,请等待工作人员完成下载。 //回显“select()ing!”; 卷曲多点选择($mh,1); //睡眠(1); } } while(false!=($info=curl\u multi\u info\u read($mh))){ 如果($info['msg']!==CURLMSG_DONE){ //不知道这是什么,这不是我们想要的信息,忽略它。 持续 } 如果($info['result']!==CURLM_OK){ $errinfo=[ “有效url”=>curl\u getinfo($info['handle',CURLINFO\u有效url), “curl\u errno”=>curl\u errno($info['handle']), “curl_error”=>curl_error($info['handle']), “curl_multi_errno”=>curl_multi_errno($mh), “curl_multi_strerror”=>curl_multi_strerror(curl_multi_errno($mh)) ]; $errstr=“curl\u多工错误:”.str\u替换([ “\r”, “\n” ],“”,变量导出($errinfo,true)); 抛出新的\RuntimeException($errstr); } $ch=$info['handle']; $ch_指数=(int)$ch; $url=$workers[$Chu索引]; $ret[$url]=curl\u multi\u getcontent($ch); 未结算($workers[$Chu index]); 卷曲多个拆卸手柄($mh,$ch); $失业工人[]=$ch; } }; $opts=数组( CURLOPT_URL=>“”, CURLOPT_RETURNTRANSFER=>1, CURLOPT_编码=>'' ); 如果(!空($附加选项)){ //我本来会使用array_merge(),但它在整数键上做了一些可怕的事情。foreach()更容易推理 foreach($key=>$val){ $opts[$key]=$val; } } foreach($url\u唯一为$url){ while(空(失业工人)){ $work(); } $new_worker=array_pop($unemployee_workers); $opts[CURLOPT_URL]=$URL; if(!curl_setopt_数组($new_worker,$opts)){ $errstr=“curl\u setopt\u数组失败:“.curl\u errno($new\u worker)。:”:“.curl\u error($new\u worker)。”“.var\u export($opts,true); 抛出新的RuntimeException($errstr); } $workers[(int)$new_worker]=$url; 卷曲多加把手($mh,$new\u worker); } 而(计数($workers)>0){ $work(); } foreach($失业工人作为$失业工人){ (失业工人); } 卷曲多重闭合($mh); 返回$ret; }
@T.Todua yes curl\u multi\u选择用于睡眠,直到有更多工作要做。当操作系统检测到有更多数据可从套接字获取时,操作系统将通知curl_multi_select,curl_multi_select将被唤醒。这可能需要100微秒,或者可能需要10微秒,或者可能需要100_000微秒,无论情况如何;(比这稍微复杂一点,如果文件上传/CURLOPT_POST时最大的上传缓冲区清理了缓冲区,或者远程主机关闭了连接,等等,curl_multi_select也会被唤醒)Matthew,谢谢你的回答。我相信这个(Guzzle)比multi-curl性能更好,我将在我的个人项目中使用它,但是,在具体的情况下(因为项目规格),我必须坚持使用native curl。否则,我会给你一个有用的答案。@T.Todua实际上,如果做得正确,curl\u multi代码应该比Guzzle更快(但在curl\u multi中犯一些影响性能的错误比在Guzzle中犯同样的错误要容易得多)@T.Todua例如,Guzzle没有实现curl句柄重用优化,但我下面的答案确实实现了curl句柄的重用,仅出于这个原因,我的curl代码在大量URL列表上使用的cpu应该比Guzzle少。@hanshenrik谢谢你,伙计,我也告诉过其他人你出色的答案/功能。您甚至可以将它作为一个独立的公共类放在Github上(就像这些家伙所做的那样:)。顺便说一句,关于回购协议,你能提两个字吗?
public function multi_curl($urls)
{          
    $AllResults =[]; 
    $mch = curl_multi_init();
    $handlesArray=[];
    $curl_conn_timeout= 3 *60; //max 3 minutes
    $curl_max_timeout = 30*60; //max 30 minutes

    foreach ($urls as $key=> $url) {
        $ch = curl_init();  
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
        curl_setopt($ch, CURLOPT_HEADER, false);
        // timeouts: https://thisinterestsme.com/php-setting-curl-timeout/   and https://stackoverflow.com/a/15982505/2377343
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $curl_conn_timeout);
        curl_setopt($ch, CURLOPT_TIMEOUT, $curl_max_timeout);
        if (defined('CURLOPT_TCP_FASTOPEN')) curl_setopt($ch, CURLOPT_TCP_FASTOPEN, 1);
        curl_setopt($ch, CURLOPT_ENCODING, ""); // empty to autodetect | gzip,deflate
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_URL, $url);
        $handlesArray[$key] = $ch;
        curl_multi_add_handle($mch, $handlesArray[$key]);
    }
   
    // other approaches are deprecated ! https://stackoverflow.com/questions/58971677/
    do {
        $execReturnValue = curl_multi_exec($mch, $runningHandlesAmount);
        usleep(100); // stop 100 microseconds to avoid infinity speed recursion
    } while ($runningHandlesAmount>0);
   
    //exec now
    foreach($urls as $key => $url)
    {
        $AllResults[$key]['url'] =$url;
        $handle = $handlesArray[$key];
        // Check for errors
        $curlError = curl_error($handle);
        if ($curlError!="")
        {
            $AllResults[$key]['error']    =$curlError;
            $AllResults[$key]['response'] =false;
        }
        else {
            $AllResults[$key]['error']    =false;
            $AllResults[$key]['response'] =curl_multi_getcontent($handle);
        }
        curl_multi_remove_handle($mch, $handle); curl_close($handle);
    }
    curl_multi_close($mch);
    return $AllResults;
}
$urls = [ 'https://baconipsum.com/api/?type=meat-and-filler',
          'https://baconipsum.com/api/?type=all-meat&paras=2'];

$results = $helpers->multi_curl($urls);