加入收藏 | 设为首页 | 会员中心 | 我要投稿 源码网 (https://www.900php.com/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 服务器 > 搭建环境 > Linux > 正文

与CURL Multi PHP不一致

发布时间:2020-12-25 10:51:23 所属栏目:Linux 来源:网络整理
导读:副标题#e# 当我对10个URL进行检查时,如果我能够与主机服务器建立连接,则句柄将返回成功消息(CURLE_OK) 当服务器拒绝连接时处理每个句柄时,句柄将包含错误消息. 问题 我假设当我们得到一个坏句柄时,CURL将标记此句柄但继续处理未处理的句柄,但这似乎不会发生
副标题[/!--empirenews.page--]

当我对10个URL进行检查时,如果我能够与主机服务器建立连接,则句柄将返回成功消息(CURLE_OK)

当服务器拒绝连接时处理每个句柄时,句柄将包含错误消息.

问题

我假设当我们得到一个坏句柄时,CURL将标记此句柄但继续处理未处理的句柄,但这似乎不会发生.
当我们遇到错误的句柄时,CURL会将此句柄标记为错误,但不会处理剩余的未处理句柄.

这可能很难检测,如果我确实得到了所有句柄的连接,这是大多数时间发生的事情,那么问题就不可见了.(CURL只在第一次错误连接时停止);

对于测试,我必须找到一个合适的站点,加载缓慢/拒绝x量同时连接.

set_time_limit(0);

$l = array(
    'http://smotri.com/video/list/','http://smotri.com/video/list/sports/','http://smotri.com/video/list/animals/','http://smotri.com/video/list/travel/','http://smotri.com/video/list/hobby/','http://smotri.com/video/list/gaming/','http://smotri.com/video/list/mult/','http://smotri.com/video/list/erotic/','http://smotri.com/video/list/auto/','http://smotri.com/video/list/humour/','http://smotri.com/video/list/film/'
);


$mh = curl_multi_init();

$s = 0;
$f = 10;

while($s <= $f)
{   

    $ch = curl_init();  

    $curlsettings = array(
        CURLOPT_URL => $l[$s],CURLOPT_TIMEOUT => 0,CURLOPT_CONNECTTIMEOUT => 0,CURLOPT_RETURNTRANSFER => 1
    );

    curl_setopt_array($ch,$curlsettings);
    curl_multi_add_handle($mh,$ch);

    $s++;

    }

$active = null;

do 
{
    curl_multi_exec($mh,$active);
    curl_multi_select($mh);

    $info = curl_multi_info_read($mh);

    echo '<pre>';
    var_dump($info);

    if($info['result'] === CURLE_OK)
        echo curl_getinfo($info['handle'],CURLINFO_EFFECTIVE_URL) . ' success<br>';

    if($info['result'] != 0)
        echo curl_getinfo($info['handle'],CURLINFO_EFFECTIVE_URL) . ' failed<br>';

} while ($active > 0);

curl_multi_close($mh);

我在脚本中抛出了$info,询问Multi Handle是否在运行时有任何句柄的新信息.
当脚本结束时,我们将看到一些bool(false) – 当没有新信息可用时(句柄仍处理),以及所有句柄如果一切成功或有限句柄,如果一个句柄失败.

我没有解决这个问题,这可能是我忽略的事情,而且我试图修复那些不相关的东西,我已经走得太远了.

一些解决这个问题的尝试是.

>将每个$ch句柄分配给一个数组 – $ch [1],$ch [2]等(而不是
将当前$ch句柄添加到multi_handle然后覆盖 – 如何
在测试中)
>成功/失败后删除句柄
curl_ MULTI_ remove_处理
>将CURLOPT_CONNECTTIMEOUT和CURLOPT_TIMEOUT设置为无穷大.

>还有更多.(我会更新这篇文章,因为我已经忘记了所有这些)

使用Php版本5.4.14进行测试
希望我已经很好地说明了这些观点.

谢谢阅读.

解决方法

我一直在尝试使用你的脚本一段时间试图让它工作.只有当我读到重复调用这个函数每次都会返回一个新的结果,直到返回一个FALSE作为一个信号,它有在这一点上没有更多内容.对于 http://se2.php.net/manual/en/function.curl-multi-info-read.php,我意识到while循环可能会起作用.

额外的while循环使其表现完全符合您的预期.这是我得到的输出:

http://smotri.com/video/list/sports/ failed

http://smotri.com/video/list/travel/ failed

http://smotri.com/video/list/gaming/ failed

http://smotri.com/video/list/erotic/ failed

http://smotri.com/video/list/humour/ failed

http://smotri.com/video/list/animals/ success

http://smotri.com/video/list/film/ success

http://smotri.com/video/list/auto/ success

http://smotri.com/video/list/ failed

http://smotri.com/video/list/hobby/ failed

http://smotri.com/video/list/mult/ failed

这是我用于测试的代码:

<?php
set_time_limit(0);

$l = array(
    'http://smotri.com/video/list/','http://smotri.com/video/list/film/'
);

$mh = curl_multi_init();

$s = 0;
$f = 10;

while($s <= $f)
{   
    $ch = curl_init();  

    if($s%2)
    {
        $curlsettings = array(
            CURLOPT_URL => $l[$s],CURLOPT_TIMEOUT_MS => 3000,CURLOPT_RETURNTRANSFER => 1,);
    }
    else
    {
        $curlsettings = array(
            CURLOPT_URL => $l[$s],CURLOPT_TIMEOUT_MS => 4000,);
    }

    curl_setopt_array($ch,$ch);
    $s++;
}

$active = null;

do 
{

    $mrc = curl_multi_exec($mh,$active);
    curl_multi_select($mh);

    while($info = curl_multi_info_read($mh))
    {
        echo '<pre>';
        //var_dump($info);

        if($info['result'] === 0)
        {
            echo curl_getinfo($info['handle'],CURLINFO_EFFECTIVE_URL) . ' success<br>';
        }
        else
        {
            echo curl_getinfo($info['handle'],CURLINFO_EFFECTIVE_URL) . ' failed<br>';
        }   
    }

} while ($active > 0);

curl_multi_close($mh);

希望有所帮助.要进行测试,只需将CURLOPT_TIMEOUT_MS调整为您的互联网连接即可.我做到了这样它在3000到4000毫秒之间交替,因为3000将失败并且4000通常成功.

更新

在浏览了PHP和libCurl文档之后,我发现curl_multi_exec是如何工作的(在libCurl中它的curl_multi_perform).在第一次被调用时,它开始处理所有添加的句柄的传输(在通过curl_multi_add_handle之前添加).

它指定$活动的数字是仍在运行的转移数量.因此,如果它小于您拥有的句柄总数,那么您就知道一个或多个传输已完成.所以curl_multi_exec也是一种进度指标.

由于所有传输都以非阻塞方式处理(传输可以同时完成),因此while循环curl_multi_exec不能代表已完成的url请求的每次迭代.

所有数据都存储在队列中,因此只要完成一个或多个传输,您就可以调用curl_multi_info_read来获取此数据.

(编辑:源码网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读