Php 在继续之前,请先完成curl multi-finish下载?

Php 在继续之前,请先完成curl multi-finish下载?,php,curl,Php,Curl,我有一组重定向的url,我想使用curl\uumulti来加速获取最终url的过程。但是当我访问CURLINFO\u有效的URL时,curl\u multi似乎还没有完成重定向,因为它返回了原始的URL function processUrls($urls){ $handlers = []; $cleanUrls = []; $mh = curl_multi_init(); foreach ($urls as $key => $url){ $

我有一组重定向的url,我想使用curl\uumulti来加速获取最终url的过程。但是当我访问CURLINFO\u有效的URL时,curl\u multi似乎还没有完成重定向,因为它返回了原始的URL

function processUrls($urls){
    $handlers = [];
    $cleanUrls = [];
    $mh = curl_multi_init();
    foreach ($urls as $key => $url){
        $handlers[$key] = curl_init();

        curl_setopt($handlers[$key], CURLOPT_URL, $url);
        curl_setopt($handlers[$key], CURLOPT_HEADER, true);
        curl_setopt($handlers[$key], CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($handlers[$key], CURLOPT_RETURNTRANSFER, true);
        curl_setopt($handlers[$key], CURLOPT_NOBODY, true);
        curl_setopt($handlers[$key], CURLOPT_HEADER, true);
        curl_multi_add_handle($mh, $handlers[$key]);
    }

    do {
        curl_multi_exec($mh, $running);
        curl_multi_select($mh);
    } while ($running > 0);

    foreach($handlers as $key => $ch){
        $cleanUrls [$key] = curl_getinfo($ch, CURLINFO_EFFECTIVE_URL) ;
    }

    curl_multi_close($mh);

    return $cleanUrls;
}
我认为问题在于这个代码:

    do {
        curl_multi_exec($mh, $running);
        curl_multi_select($mh);
    } while ($running > 0);

使用stream_socket_客户端有一种更高效、更灵活的方法。每个url都没有延迟。一个url的缓慢响应不会影响其他url的响应时间。回复将以先到先得的方式返回。如果需要,您可以按顺序获得响应

如果我理解正确,您希望发出一些响应时间不可预测或太长而无法连续运行的HTTP请求,并且希望同时运行该请求

我在运行W3C验证工具时会这样做。 我做CSS验证、HTML验证和XHTML验证。我喜欢我的代码尽可能多地使用XHTML,并且只在必要时使用HTML5。旧的W3C移动最佳实践习惯

在传输HTML之前,我使用stream\u socket\u客户端启动并发请求

这与PHP实现的多任务差不多。这是我已经使用了几年的实际工作代码

初始化变量。 $url是测试页面的完全限定url,例如

使用stream\u socket\u客户端发出请求 请求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";
    }
  }
HTTP响应存储在$result[]数组中

您必须添加对重定向响应的搜索,然后进行后续请求

此代码为您提供完全控制。没有隐藏,没有未知


如果您想放弃一些控制以便于使用。对自己的脚本发出请求,并使用正则curl执行请求和重定向

您在哪里定义$running?是的,这部分代码很复杂。运行是在curl\u multi\u exec参数中设置的
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";
    }
  }
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) { 
        $closed[$id] = microtime(true);  // not necessary
        fclose($r); 
        unset($sockets[$id]);

        // check $response[$id] for redirect here


      } 
      else {
        $result[$id] .= $data; 
      }
    }
  }
  else { 
 //   echo 'Timeout: ' . date('h:i:s') . "\n\n\n";
    break;
  }
}