1

curl_multi_*連続して取得するのに時間がかかるため、複数(約50)のURLを同時に取得するために使用しようとしています。ただし、を実行すると次のエラーメッセージが表示されますcurl_multi_add_handle

警告:(null)():10は0行目の不明の有効なcURLハンドルリソースではありません

コードは次のとおりです。

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

// Loop over pages and get set the URL to the cURL queue
foreach ($htmltogetlist as $source) {

    [...]

    // Get a cURL handle of the current URL
    $urls[$id]['ch'] = $this->_getCurlHandle($urls[$id]['url']);

    // Success
    if (gettype($urls[$id]['ch']) == 'resource' && get_resource_type($urls[$id]['ch']) == 'curl') {
        curl_multi_add_handle($mh, $urls[$id]['ch']); // << Produces error
    }
}

そして$this->_getCurlHandle持っている:

// Set cURL handle
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_ENCODING , "gzip");
curl_setopt($ch, CURLOPT_REFERER, $url);
curl_setopt($ch, CURLOPT_USERAGENT, 'PHP');
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_AUTOREFERER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 10);

return $ch;

奇妙なことに、それはタイプ$urls[$id]['ch']の有効なものですが、それを追加することはできず、エラーはのファイルにあります。実際には、ハンドルを実行して正しい応答を取得することもできるので、それが有効であると確信しています。に追加できません。resourcecurl$mhunknownline 0$mh

$content = curl_exec($urls[$id]['ch']);
$response = curl_getinfo($urls[$id]['ch']);
print_r($response); // Works

cURLが複数の転送で機能していることを知っています。たとえば、次のコード(基本的に同じことを行います)は機能します。また、データベースクエリを1に制限すると同じエラーが発生するため、問題の原因はURLの数ではないと確信しています。

$ch1 = curl_init();
$ch2 = curl_init();

// set URL and other appropriate options
curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/");
curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/");

curl_setopt($ch1,CURLOPT_ENCODING , "gzip");
curl_setopt($ch1, CURLOPT_REFERER, $url);
curl_setopt($ch1, CURLOPT_USERAGENT, 'PHP');
curl_setopt($ch1, CURLOPT_HEADER, true);
curl_setopt($ch1, CURLOPT_AUTOREFERER, true);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch1, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch1, CURLOPT_TIMEOUT, 10);

curl_setopt($ch2,CURLOPT_ENCODING , "gzip");
curl_setopt($ch2, CURLOPT_REFERER, $url);
curl_setopt($ch2, CURLOPT_USERAGENT, 'PHP');
curl_setopt($ch2, CURLOPT_HEADER, true);
curl_setopt($ch2, CURLOPT_AUTOREFERER, true);
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch2, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch2, CURLOPT_TIMEOUT, 10);

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

//add the two handles
curl_multi_add_handle($mh,$ch1); // Works
curl_multi_add_handle($mh,$ch2); // Works
4

2 に答える 2

3

上記のコメントでRichardが言及した問題#61141を確認したところ、pierrickが提供した解決策で実際にエラーが修正されました。

これは、PHPマニュアルに記載されている、基本的なmulticurlexecセットアップです。

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

ただし、正しい設定は次のようになります。

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

-1が返された場合curl_multi_selectは、スクリプトをしばらく停止してから、curl_mutli_execとにかく実行します。

詳細については、https ://bugs.php.net/bug.php?id=61141をご覧ください。

于 2014-01-27T14:05:02.443 に答える
0

PHP 5.3.23、curl7.30.0を使用するOSXでこれに遭遇しました。

修正は、curl_multi_init()の前にすべてのcurl_init()が呼び出されるようにすることでした。

他のプラットフォーム(つまりLinux)ではこれを見たことがありません

于 2013-08-14T16:54:19.400 に答える