【问题标题】:php multiple curl urls with while loop带有while循环的php多个curl url
【发布时间】:2016-07-24 05:16:09
【问题描述】:

我正在开发一个小脚本,但我对使用几个 curl 和 while 循环有点搞砸了。

我想在某个 URL 向我提供信息时停止处理 curl。注意:我有多个 curl 请求。

所以我的概念是,

我有几个 URL,我必须处理并从中获取信息。如果在特定 URL 上找到信息,它将给我一个字符串。如果没有找到任何信息,它会给我任何价值。所以我大约有近 10 个 URL 需要处理。在所有情况下,任何一个 URL 都会给我信息,所以剩余的 url 将不会产生任何价值。由于处理了很多 URL,因此延迟是一个问题。所以假设在下面的示例代码中,如果 url 以 value2.php 结尾给我一个结果,那么我立即想停止处理其他 URL。因为我已经得到了结果,并且没有必要运行其他 curl。然后最后我必须打印结果。

另外,我有一个 URL 没有产生任何结果的情况,如果有人告诉我如何处理它,那就太好了。

我的示例代码。

<?php
///functions here
do {

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"example[dot]com/value1.php?process=$param");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$combined = curl_exec ($ch);
curl_close ($ch);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"example[dot]com/value2.php?process=$param");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$combined = curl_exec ($ch);
curl_close ($ch);


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"example[dot]com/value3.php?process=$param");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$combined = curl_exec ($ch);
curl_close ($ch);


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"example[dot]com/value4.php?process=$param");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$combined = curl_exec ($ch);
curl_close ($ch);


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"example[dot]com/value5.php?process=$param");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$combined = curl_exec ($ch);
curl_close ($ch);


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"example[dot]com/value6.php?process=$param");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$combined = curl_exec ($ch);
curl_close ($ch);


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"example[dot]com/value7.php?process=$param");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$combined = curl_exec ($ch);
curl_close ($ch);


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"example[dot]com/value8.php?process=$param");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$combined = curl_exec ($ch);
curl_close ($ch);


$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"example[dot]com/value9.php?process=$param");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$combined = curl_exec ($ch);
curl_close ($ch);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"example[dot]com/value10.php?process=$param");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$combined = curl_exec ($ch);
curl_close ($ch);

} while (strlen($combined) != 0);
echo $combied;

///functions here

?>

【问题讨论】:

  • 你的网址是常量吗?你为什么不只调用一个调用 curl 并使用一系列地址,直到你的结果对你来说足够?
  • 是的,所有 URL 都是不变的,但每个 URL 都是不同的。如果第三个 url 给了我结果,我怎么能停止处理 curl 。我必须处理一个while循环并对此感到震惊。
  • 找到结果后是否有必要停止?换句话说,它们是否必须以特定的顺序执行,而改变顺序会搞砸,还是没关系?
  • @Mike 是的,如果找到结果,则有必要停止该过程。因为一旦我得到结果,就没有必要处理剩余的 URL,因为所有剩余的 URL 都不会给我任何结果。不,不需要任何特定的处理顺序。更改顺序完全没问题。
  • 好的,所以没有必要,只是首选。我会在几分钟后发布一个不同的答案。

标签: php url curl while-loop do-while


【解决方案1】:

就像您在问题中拥有它以及其他答案如何拥有它一样,问题是对于每个请求,您必须发送它,等待响应,处理数据,然后只有 然后 这样做您提出后续请求。这工作正常,但时间效率非常低。例如,每个请求需要 100 毫秒来完成(这可能并非不切实际)。对于 10 个请求,您正在查看 1 秒的加载时间。相反,我建议您在找到结果并发送所有请求后忘记尝试停止发出请求...同时。这可以通过 PHP 的 curl_multi_* 函数来完成。

// Put all of your URLs in here. I'm just using google for
// all as an example:
$urls[] = 'http://www.google.com';
$urls[] = 'http://www.google.com';
$urls[] = 'http://www.google.com';
$urls[] = 'http://www.google.com';
$urls[] = 'http://www.google.com';
$urls[] = 'http://www.google.com';

// Get cURL handles
foreach ($urls as $key => $url) {
    $chs[$key] = curl_init();

    // Set all your options for each connection here
    curl_setopt($chs[$key], CURLOPT_URL, $url);
    curl_setopt($chs[$key], CURLOPT_HEADER, 0);
}

//create the multiple cURL handle
$mh = curl_multi_init();

//add the handles
foreach ($chs as &$ch) {
    curl_multi_add_handle($mh,$ch);
}

$active = null;
//execute the handles
do {
    $mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);

while ($active && $mrc == CURLM_OK) {
    if (curl_multi_select($mh) != -1) {
        do {
            $mrc = curl_multi_exec($mh, $active);
        } while ($mrc == CURLM_CALL_MULTI_PERFORM);
    }
}

foreach ($chs as $url=>&$ch) {
    $html = curl_multi_getcontent($ch);

    // [do what you want with the HTML]

    curl_multi_remove_handle($mh, $ch); // remove the handle (assuming  you are done with it);
}

curl_multi_close($mh);

【讨论】:

    【解决方案2】:

    尝试以下方法:

    <?php
    
    function callCURL($url) {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $combined = curl_exec ($ch);
        curl_close ($ch);
        return $combined;
    }
    
    
    function getResult($urls) {
        $return = array();
    
        foreach ($urls as $url) {
            $response = callCURL($url);
            if (strlen($response) !== 0) {
                $return[] = $response;
                break;
            }
        }
        return $return;
    }
    
    $urls = array("example.com/value1.php?process=$param", "example.com/value2.php?process=$param", "example.com/value3.php?process=$param")
    
    $result = getResult($urls);
    

    【讨论】:

    • 这很好,伙计。正如其他人推荐的那样,你能用 curl multi 更新这个答案吗?
    【解决方案3】:

    您可以使用for 循环来实现此目的。

    $fileNames = array(
       '0' => 'valueabc',
       '1' => 'valuedef',
       [...] => [...]
    );
    $combined = array();
    for ($i = 1; $i < 10; $i++)
    {
        $ch = curl_init();
        $url = "example[dot]com/" . $fileNames[$i] . ".php?process=" . $param;
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        $combined[$i] = curl_exec ($ch);
        curl_close ($ch);
    }
    

    要查看所有回复,您可以foreach $combined

    foreach ($combined as $value=>$response)
    {
        // TODO: Work with the response
        echo "[" . $value . "]" . $response;
    }
    

    【讨论】:

    • 您好,Kyle,感谢您提供示例代码。但在我的情况下,我的问题中发布的代码被编辑以公开隐藏真实的页面名称。实际上 url 看起来像 example[dot]com/mypageabc.php?process=$param, example[dot]com/mypagedef.php?process=$param 等等,不是任何数值
    • 哦,那么抱歉。将名称粘贴在数组中并将 /value$i 中的 $i 替换为 $arrayOfFileNames[$i] 怎么样? - 生病更新它。
    • 我会考虑一种更面向对象的方法,并且可能会使用构造函数。不过祝你好运。
    【解决方案4】:

    你可以使用这样的东西。我没有检查代码,调试后它应该可以工作。

    function callcurl($url) 
    {
      $ch = curl_init();
      curl_setopt($ch, CURLOPT_URL,"example[dot]com/value5.php?process=$param");
      curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
      $ret = curl_exec ($ch);
      curl_close ($ch);
    }
    
    $urls = array('url1', 'url2'); /// etc
    $combined = ''
    $cnt = 0;
    do {
      $combined = callcurl($urls[$cnt++]);
    } while (strlen($combined) != 0 && $cnt < count($urls)); //
    
    print $combined;
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-08-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2015-07-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多