【问题标题】:PHP defining multible curls via arrayPHP通过数组定义多个url
【发布时间】:2011-05-15 18:44:43
【问题描述】:

尝试为 curl 处理程序创建 5 个 curl 子项并定义它们,但找不到最好的方法..我的代码到目前为止

$curls = array($ch1, $ch2, $ch3, $ch4, $ch5); // have a bad feelin about this
$cont = array($cont1, $cont2, $cont3, $cont4, $cont5); // bad

for($i = 0; $i < count($curls); $i++) { // bad
    $curls[$i] = curl_init();

    curl_setopt($curls[$i], CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curls[$i], CURLOPT_FOLLOWLOCATION, true);

    curl_setopt($curls[$i], CURLOPT_REFERER, $ref);
    curl_setopt($curls[$i], CURLOPT_USERAGENT, $useragent);

    curl_setopt($curls[$i], CURLOPT_COOKIEFILE, $cookiefile);
    curl_setopt($curls[$i], CURLOPT_COOKIEJAR, $cookiefile);

    curl_setopt($curls[$i], CURLOPT_URL, $url);
    curl_setopt($curls[$i], CURLOPT_POST, true);
    curl_setopt($curls[$i], CURLOPT_POSTFIELDS, $data);
    $cont[$i] = curl_exec($curls[$i]); //  bad

    curl_setopt($curls[$i], CURLOPT_URL, $url);
    curl_setopt($curls[$i], CURLOPT_POST, true);
    curl_setopt($curls[$i], CURLOPT_POSTFIELDS, $data);
    $cont[$i] = curl_exec($curls[$i]); // bad
}

以后:

$mh = curl_multi_init();

curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);
curl_multi_add_handle($mh,$ch3);
curl_multi_add_handle($mh,$ch4);
curl_multi_add_handle($mh,$ch5);

这行得通吗,或者..这是最佳方式吗?好像有点颠簸

【问题讨论】:

  • 为什么要在定义它们的循环中执行句柄?多句柄的意义不在于并行吗?
  • @Tim Yates:嗯,他们还没有做并行处理,他们一个一个地登录,当他们都登录时,他们开始做并行工作
  • 您需要登录不同的帐户还是每个帐户?不能只在一次登录后共享 cookie 文件吗?
  • $Ryan Pendelton:与所有 5 个 curl 孩子相同的帐户,共享 cookie 文件?怎么样?

标签: php arrays curl


【解决方案1】:

我实际上会以不同的方式处理这个问题。我将创建一个函数来处理curl 的单个实例的创建,并根据需要使用参数来调整变量设置。这让我可以创建一个实例,或者我可以创建一个循环来创建多个实例。

问题是,多次 curl 调用取决于上一次调用是否成功。如果第一个不成功,我现在浪费了多个 curl 对象。创建第一个,运行它,错误检查,创建第二个,运行它,错误检查,等等。这样你只分配你需要的东西。

编辑:像这样

// get the result of a single curl call
function makeCurlCall($ref, $useragent, $cookiefile, $url, $data)
{
    $curl = curl_init();

    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);

    curl_setopt($curl, CURLOPT_REFERER, $ref);
    curl_setopt($curl, CURLOPT_USERAGENT, $useragent);

    curl_setopt($curl, CURLOPT_COOKIEFILE, $cookiefile);
    curl_setopt($curl, CURLOPT_COOKIEJAR, $cookiefile);

    curl_setopt($curl, CURLOPT_URL, $url);
    curl_setopt($curl, CURLOPT_POST, true);
    curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    $cont = curl_exec($curl);

    // May need to use this later
    $error_no = curl_errno($curl);

    if($error_no) {
      // so we can close before we return
      $result = "[" . $error_no . "] " . curl_error($curl);
      curl_close($curl);
      return array('status' => 'error', 'result' => $result);
    }
    else {
      curl_close($curl);
      return array('status' => 'success', 'result' => $cont);
    }
}

$curl = makeCurlCall($ref, $useragent, $cookiefile, $url, $data);
if($curl['status'] == 'error') {
  // do something for the error
}
else { 
  // do something with $curl['result']
}

// The first call worked, so make the next call, only allocating what we need
$curl = makeCurlCall($ref, $useragent, $cookiefile, $url, $data);

//etc.

请注意,如果足够通用,您可能会包含处理错误和成功的功能,但您仍然需要处理由于网络问题等原因导致单个 curl 调用不起作用的问题。

【讨论】:

  • 你能添加一些代码吗?我不太清楚你的意思
【解决方案2】:

你可以试试这样的。我不确定它是否适用于您的场景,但这是一个开始。

function makeCurl($ref, $useragent, $cookiefile, $url, $data){
    $curl = curl_init();

    curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);

    curl_setopt($curl, CURLOPT_REFERER, $ref);
    curl_setopt($curl, CURLOPT_USERAGENT, $useragent);

    curl_setopt($curl, CURLOPT_COOKIEFILE, $cookiefile);
    curl_setopt($curl, CURLOPT_COOKIEJAR, $cookiefile);

    curl_setopt($curl, CURLOPT_URL, $url);

    if($data){
        curl_setopt($curl, CURLOPT_POST, true);
        curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
    }

    return $curl;
}

// first let's login

$login = makeCurl($loginref, $useragent, $cookiefile, $loginurl, $logindata);
curl_exec($login);
curl_close($login);

// $cookiefile now has the needed cookies
// for the parallel jobs to run

$curls = array();
$mh = curl_multi_init();

$curls[0] = makeCurl($ref, $useragent, $cookiefile, $url, $data);
$curls[1] = makeCurl($ref, $useragent, $cookiefile, $url, $data);
$curls[2] = makeCurl($ref, $useragent, $cookiefile, $url, $data);
$curls[3] = makeCurl($ref, $useragent, $cookiefile, $url, $data);
$curls[4] = makeCurl($ref, $useragent, $cookiefile, $url, $data);
$curls[5] = makeCurl($ref, $useragent, $cookiefile, $url, $data);

for($i = 0; $i < count($curls); $i++){
    curl_multi_add_handle($mh, $curls[$i]);
}

// use curl_multi_exec to run them and wait for them to finish
// (I've never done this before, so i can't tell you how to do it)

【讨论】:

    猜你喜欢
    • 2017-05-26
    • 1970-01-01
    • 2012-02-23
    • 2016-05-14
    • 1970-01-01
    • 2019-11-28
    • 2011-05-23
    • 2021-03-05
    • 2021-04-02
    相关资源
    最近更新 更多