当我需要传递自定义选项时,如何使用PHP curl_multi_init()用法?

当我需要传递自定义选项时,如何使用PHP curl_multi_init()用法?,php,curl,remote-server,Php,Curl,Remote Server,我有一个自定义的cURL函数,它必须从远程服务器下载大量图像。我在使用file_get_contents()时被禁止了几次。我发现curl_multi_init()是更好的选择,因为使用1个连接,它可以一次下载20个图像。 我制作了一个使用curl_init()的自定义函数,我正在尝试如何实现curl_multi_init(),因此在我的循环中,我从数据库中获取20个URL的列表,我可以调用我的自定义函数,并在最后一个循环中使用curl_close()。在当前情况下,我的函数为循环中的每个url

我有一个自定义的cURL函数,它必须从远程服务器下载大量图像。我在使用file_get_contents()时被禁止了几次。我发现curl_multi_init()是更好的选择,因为使用1个连接,它可以一次下载20个图像。 我制作了一个使用curl_init()的自定义函数,我正在尝试如何实现curl_multi_init(),因此在我的循环中,我从数据库中获取20个URL的列表,我可以调用我的自定义函数,并在最后一个循环中使用curl_close()。在当前情况下,我的函数为循环中的每个url生成连接。以下是函数:

function downloadUrlToFile($remoteurl,$newfileName){
$errors = 0;
    $options = array(
      CURLOPT_FILE    => fopen('../images/products/'.$newfileName, 'w'),
      CURLOPT_TIMEOUT =>  28800,
      CURLOPT_URL     => $remoteurl,
      CURLOPT_RETURNTRANSFER => 1
    );

    $ch = curl_init();
    curl_setopt_array($ch, $options);
    $imageString =curl_exec($ch);
    $image = imagecreatefromstring($imageString);
    if($imageString !== false AND !empty($imageString)){
    if ($image !== false){
        $width_orig = imagesx($image);
        if($width_orig > 1000){
        $saveimage = copy_and_resize_remote_image_product($image,$newfileName);
        }else $saveimage = file_put_contents('../images/products/'.$newfileName,$imageString);
        
        }else $errors++;
    }else $errors++;
    curl_close($ch);
    return $errors;
}
必须有一种方法可以使用curl_multi_init()和我的函数downloadUrlToFile,因为:

  • 我需要动态更改文件名
  • 在我的功能中,我还检查了远程图像的一些内容。。在示例函数中,我只检查大小,并在必要时调整大小,但此函数可以完成更多操作(我缩短了该部分,但我还使用该函数传递更多变量..)
  • 如何在循环期间更改代码,使其只连接到远程服务器一次


    提前感谢

    尝试此模式进行多次卷曲

    $urls = array($url_1, $url_2, $url_3);
    $content = array();
    
    $ch = array();
    $mh = curl_multi_init();
    
    foreach( $urls as $index => $url ) {
        $ch[$index] = curl_init();
        curl_setopt($ch[$index], CURLOPT_URL, $url);
        curl_setopt($ch[$index], CURLOPT_HEADER, 0);
        curl_setopt($ch[$index], CURLOPT_RETURNTRANSFER, true);
        curl_multi_add_handle($mh, $ch[$index]);
    }
    
    $active = null;
    for(;;) {
        curl_multi_exec($mh, $active);
        if($active < 1){
            // all downloads completed
            break;
        }else{
            // sleep-wait for more data to arrive on socket.
            // (without this, we would be wasting 100% cpu of 1 core while downloading,
            // with this, we'll be using like 1-2% cpu of 1 core instead.)
            curl_multi_select($mh, 1);
        }
    }
    
    foreach ( $ch AS $index => $c ) {
    
        $content[$index] = curl_multi_getcontent($c);
        curl_multi_remove_handle($mh, $c);
    
        //You can add some functions here and use $content[$index]
    }
    
    curl_multi_close($mh);
    
    $url=array($url\u 1、$url\u 2、$url\u 3);
    $content=array();
    $ch=array();
    $mh=curl_multi_init();
    foreach($url作为$index=>$url){
    $ch[$index]=curl_init();
    curl_setopt($ch[$index],CURLOPT_URL,$URL);
    curl_setopt($ch[$index],CURLOPT_头,0);
    curl_setopt($ch[$index],CURLOPT_RETURNTRANSFER,true);
    curl_multi_add_句柄($mh,$ch[$index]);
    }
    $active=null;
    对于(;;){
    curl_multi_exec($mh,$active);
    如果($active<1){
    //所有下载已完成
    打破
    }否则{
    //睡眠等待更多数据到达套接字。
    //(如果没有这一点,我们将在下载时浪费100%的1核cpu,
    //有了这个,我们将使用1核1-2%的cpu。)
    卷曲多点选择($mh,1);
    }
    }
    foreach($ch AS$index=>$c){
    $content[$index]=curl\u multi\u getcontent($c);
    卷曲多柄取下手柄($mh,$c);
    //您可以在此处添加一些函数并使用$content[$index]
    }
    卷曲多重闭合($mh);
    
    #亚历山大,谢谢你抽出时间。当我发现使用类似的代码时,我无法传递所需的几个变量,这是我的第一种方法。如果我可以的话,这个代码可能对我有用,但是。。例如,我需要传递:产品标识、产品名称、产品代码。。在我的示例函数中,我只显示了产品名称,但我解释说,实际上我发送的变量更多,而不是使用busylop;这将毫无理由地浪费100%的cpu(1个cpu核心)。相反,请尝试:
    for(;){curl_multi_exec($mh,$active);如果($active#hanshenrik什么是Busylop?这是对Alexander的回答的评论吗?@hanshenrik谢谢你的建议,这是一个很好的观点。@Europeuser你可以读到,Alexander的原始代码有一个问题,它会比实际需要多使用98%的cpu。但不管怎样,代码已经更新了,这个问题仍然存在固定:)