阻止在multi_curl中花费太多时间的单个URL /请求并继续其余请求

时间:2017-02-11 15:50:53

标签: php curl curl-multi

如何在PHP中的multi_curl中阻止/超出单个请求,这会占用太多时间而不影响剩余请求

1 个答案:

答案 0 :(得分:0)

如果我理解正确,你想做一些HTTP请求,其中响应时间可能无法预测或者太长而无法连续运行并希望同时运行请求。

我在运行W3C验证工具时这样做 我做CSS验证,HTML验证和XHTML验证。 (我喜欢我的代码使用和XHTML一样多,只在必要时使用HTML5。老W3C移动最佳习惯习惯。)

在传输stream_socket_client()之前。

这与PHP获得的多任务一样接近。

初始化变量。

$ url是受测试网页的完全限定网址,例如http://example.com/index.html

  $url = $_POST['url'];
  $webPageTestKey = ' [key for WebPageTest.org goes here] ';
  $timeout = 120; 
  $result = array(); 
  $sockets = array(); 
  $buffer_size = 8192;
  $id = 0;
  $urls = array();
  $path = $url;
  $url = urlencode("$url");

使用stream_socket_client()

进行请求

请求网址存储在$ urls []数组

  $urls[] = array('host' => "jigsaw.w3.org",'path' => "/css-validator/validator?uri=$url&profile=css3&usermedium=all&warning=no&lang=en&output=text");
  $urls[] = array('host' => "validator.w3.org",'path' => "/check?uri=$url&charset=%28detect+automatically%29&doctype=Inline&group=0&output=json");
  $urls[] = array('host' => "validator.w3.org",'path' => "/check?uri=$url&charset=%28detect+automatically%29&doctype=XHTML+Basic+1.1&group=0&output=json");
  $urls[] = array('host' => "www.webpagetest.org",'path' => "/runtest.php?f=xml&bwDown=10000&bwUp=1500&latency=40&fvonly=1&k=$webPageTestKey&url=$url");

套接字需要主机和路径 如果你不能轻易看到url的格式转储数组

var_export($urls);

续:

  $err = '';
  foreach($urls as $path){
    $host = $path['host'];
    $path = $path['path'];
    $http = "GET $path HTTP/1.0\r\nHost: $host\r\n\r\n";
    $stream = stream_socket_client("$host:80", $errno,$errstr, 120,STREAM_CLIENT_ASYNC_CONNECT|STREAM_CLIENT_CONNECT); 
    if ($stream) {
      $sockets[] = $stream;  // supports multiple sockets
      $start[] = microtime(true);
      fwrite($stream, $http);
    }
    else { 
   $err .=  "$id Failed<br>\n";
    }
  }

请求套接字存储在数组$ sockets []

然后我在等待请求完成时传输HTML。强文

使用stream_select()

检索对请求的响应

回复按照收到的顺序返回。请求的顺序无关紧要。

通过8K缓冲区读入响应。如果响应超过8K,则一次检索8K多个块。

while (count($sockets)) {
  $read = $sockets; 
  stream_select($read, $write = NULL, $except = NULL, $timeout);
  if (count($read)) {
    foreach ($read as $r) { 
      $id = array_search($r, $sockets); 
      $data = fread($r, $buffer_size); 
      if (strlen($data) == 0) { 
     //   echo "$id Closed: " . date('h:i:s') . "\n\n\n";
        $closed[$id] = microtime(true);  // not necessary
        fclose($r); 
        unset($sockets[$id]);
      } 
      else {
        $result[$id] .= $data; 
      }
    }
  }
  else { 
 //   echo 'Timeout: ' . date('h:i:s') . "\n\n\n";
    break;
  }
}

HTTP响应存储在$ result []数组中。