php单卷曲有效,但多卷曲无效;不起作用


php single curl works but multi curl doesn't work?

所以我使用ampps,然后切换到z-wamp,认为它可以解决问题,但它没有。

我在本地主机(localhost/site1&localhost/site2)中有单独的"站点",我正试图向它们发送多卷曲请求,但出于某种奇怪的原因,它什么都没做!只有当我对一个站点进行一次卷曲时,它才有效。这项工作:

$ch = curl_init('http://localhost/site1/');
curl_setopt_array($ch, array(
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HEADER => false,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => array('data' => $data)
));
$res = curl_exec($ch);
//yay!

另一方面,这不起作用:

...
//add a bunch of curl sessions
//to $this->sessions
...
$window = 15;
if (count($this->sessions) < $window)
    $window = count($this->sessions);
$mh = curl_multi_init();
$site_map = array();
for ($i = 0; $i < $window; ++$i) {
    curl_multi_add_handle($mh, $this->sessions[$i]);
    $site_map[(string) $this->sessions[$i]] = $i;
}
$data_results = array();
$running = null;
do {
    $execrun = curl_multi_exec($mh, $running);
} while ($execrun === CURLM_CALL_MULTI_PERFORM);
while ($running && $execrun === CURLM_OK) {
    //the loop just keeps going forever from here
    if (curl_multi_select($mh) !== -1) {
        do {
            $execrun = curl_multi_exec($mh, $running);
        } while ($execrun === CURLM_CALL_MULTI_PERFORM);
    }
    if ($execrun !== CURLM_OK)
        break;
    //to here and never enters the loop below
    while ($done = curl_multi_info_read($mh)) {
        $output = curl_multi_getcontent($done['handle']);
        if ($output)
            $data_results[$site_map[(string) $done['handle']]] = $output;
        else
            $data_results[$site_map[(string) $done['handle']]] = null;
        if (isset($this->sessions[$i]) && $i < count($this->sessions)) {
            curl_multi_add_handle($mh, $this->sessions[$i]);
            $site_map[(string) $this->sessions[$i]] = $i;
            ++$i;
        }
        unset($site_map[(string) $done['handle']]);
        curl_multi_remove_handle($mh, $done['handle']);
        curl_close($done['handle']);
    }
}
curl_multi_close($mh);
return $data_results;

因此,在上面的multi-ccurl代码中,它开始执行,将句柄添加到$mh,一旦执行,它将保持循环,永远不会进入$done=curl_multi_info_read($mh)while循环。同时它仍然运行良好,并且$running始终等于2。此外,curl_multi_info_read将返回false。所以它永远都在循环。

我的curl扩展已经启用(显然,如果单个curl有效的话),下面是PHP Info:中的详细信息

cURL support    enabled
cURL Information    7.24.0
Age 3
Features
AsynchDNS   Yes
Debug   No
GSS-Negotiate   No
IDN No
IPv6    Yes
Largefile   Yes
NTLM    Yes
SPNEGO  No
SSL Yes
SSPI    No
krb4    No
libz    Yes
CharConv    No
Protocols   dict, file, ftp, ftps, gopher, http, https, imap, imaps, ldap, pop3, pop3s, rtsp, scp, sftp, smtp, smtps, telnet, tftp
Host    i386-pc-win32
SSL Version OpenSSL/1.0.0g
ZLib Version    1.2.5
libSSH Version  libssh2/1.3.0

这东西到底是怎么回事?这可能是我的PHP配置的问题吗?Apache配置?再一次,我使用z-wamp。

PHP版本5.3.10Apache版本2.4.1Win 7 64位将PHP目录添加到PATH

编辑事实证明,这一定是某种Apache/PHP配置类型的问题,我根本无法发现,因为我取消了z-wamp并安装了wampserver,这次它成功了。

我刚刚回答了另一个关于多个curl调用的问题。

这就是我运行请求所做的全部操作。

do {
    $status = curl_multi_exec($mh, $running);
} while ($status === CURLM_CALL_MULTI_PERFORM || $running);

然后,我通过循环我的卷曲处理程序数组来获取我需要的信息。

$returned = array();
foreach ($requests as $identifier => $request) {
    $returned[$identifier] = curl_multi_getcontent($request);
    curl_multi_remove_handle($mh, $request);
    curl_close($request);
}

上面的方法对我很有效,但是您似乎只想向curl多处理程序添加一定数量的会话。我们可能会将上面的do while循环更改为以下内容:

do {
    $status = curl_multi_exec($mh, $running);
    if ($running < $window) {
        for ($x = 0; $x < $window - $running; $x++) {
            $index = count($site_map) + $x -1;
            curl_multi_add_handle($mh, $this->sessions[$index]);
            $site_map[(string) $this->sessions[$index]] = $index;
        }
    }
} while ($status === CURLM_CALL_MULTI_PERFORM || $running);

之后,我们可以修改数据提取,并用以下内容替换整个while ($running && $execrun === CURLM_OK){}部分,因为它只有在处理完所有curl调用后才会运行:

$returned = array();
foreach ($this->sessions as $identifier => $request) {
    $returned[$identifier] = curl_multi_getcontent($request);
    curl_multi_remove_handle($mh, $request);
    curl_close($request);
}

我曾尝试在同一页上同时运行单个curl_exec()curl_multi_exec(),但也没有得到响应,直到我在单个请求之后才得到响应:unset($ch);