【问题标题】:PHP - curl_multi_exec never completesPHP - curl_multi_exec 永远不会完成
【发布时间】:2017-07-17 19:36:43
【问题描述】:

我已经尝试了许多使用curl_multi_exec 的在线示例。不幸的是,它们都没有为我“工作”,因为它们永远阻塞并且我从未得到回应。

我尝试修改一些示例,以便在我得到一个无效的 -1 响应时它们会休眠(除了停止我的 CPU 达到 100%)。我在 CLI 和作为网络服务器运行都进行了尝试,结果相同。

问题:这些脚本是否适用于其他人,或者他们是否需要针对 PHP 7.0 进行修改/更新?也许我需要安装除 php7.0-curl 以外的软件包?

环境

我在 Ubuntu 16.04 上运行 PHP 7.0:

PHP 7.0.18-0ubuntu0.16.04.1 (cli) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies
    with Zend OPcache v7.0.18-0ubuntu0.16.04.1, Copyright (c) 1999-2017, by Zend Technologies

【问题讨论】:

    标签: php curl


    【解决方案1】:

    正如http://php.net/manual/en/function.curl-multi-init.php#115055的评论所说,官方文档有问题。所以示例 2 的类应该看起来像这样。更改了第一个 while 循环

    class ParallelGet
    {
      function __construct($urls)
      {
        // Create get requests for each URL
        $mh = curl_multi_init();
        foreach($urls as $i => $url)
        {
          $ch[$i] = curl_init($url);
          curl_setopt($ch[$i], CURLOPT_RETURNTRANSFER, 1);
          curl_multi_add_handle($mh, $ch[$i]);
        }
    
        // Start performing the request
        do {
            $execReturnValue = curl_multi_exec($mh, $runningHandles);
        } while ($execReturnValue == CURLM_CALL_MULTI_PERFORM);
    
        // Loop and continue processing the request
        while ($runningHandles && $execReturnValue == CURLM_OK) {
    
          // !!!!! changed this if and the next do-while !!!!!
    
          if (curl_multi_select($mh) != -1) {
            usleep(100);
          }
    
          do {
            $execReturnValue = curl_multi_exec($mh, $runningHandles);
          } while ($execReturnValue == CURLM_CALL_MULTI_PERFORM);
    
        }
    
        // Check for any errors
        if ($execReturnValue != CURLM_OK) {
          trigger_error("Curl multi read error $execReturnValue\n", E_USER_WARNING);
        }
    
        // Extract the content
        foreach($urls as $i => $url)
        {
          // Check for errors
          $curlError = curl_error($ch[$i]);
          if($curlError == "") {
            $res[$i] = curl_multi_getcontent($ch[$i]);
          } else {
            print "Curl error on handle $i: $curlError\n";
          }
          // Remove and close the handle
          curl_multi_remove_handle($mh, $ch[$i]);
          curl_close($ch[$i]);
        }
        // Clean up the curl_multi handle
        curl_multi_close($mh);
    
        // Print the response data
        print_r($res);
      }
    }
    

    【讨论】:

    • 您已经回答了我发布的问题,因此我将其标记为完整答案。我认为我的下一个问题属于一个单独的问题,但是您是否碰巧知道为什么它们没有异步发送而是将在队列中处理。例如。在使用 sleep(10) 运行本地主机网络服务器后,尝试运行以下代码 pastebin.com/ngu8L3kk,您将看到您没有获得 google 或 yahoo 结果,直到第一个请求的 10 秒过去。此外,如果您只使用多个 localhost 请求,则需要的时间将与请求数 x 10 秒一样长。
    • 对不起,我不太明白出了什么问题,我建议提出一个新问题,我会找到的。
    • 谢谢,再调查一下就可以了。
    • 我发现我在测试时做错了。所有排序:)
    猜你喜欢
    • 1970-01-01
    • 2017-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    相关资源
    最近更新 更多