阻止multi_curl中花费太多时间的单个URL/Request,并继续处理剩余的请求



我们如何在PHP中阻止/超时multi_curl中花费太多时间的单个请求,同时不影响剩余的请求

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

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

在传输stream_socket_client()之前

这与PHP的多任务处理差不多

初始化变量

$url是测试页面的完全限定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()发出请求

请求URL存储在$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.0rnHost: $hostrnrn";
$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[]中

然后我在等待请求完成的同时传输HTMLstrong文本

使用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') . "nnn";
$closed[$id] = microtime(true);  // not necessary
fclose($r); 
unset($sockets[$id]);
} 
else {
$result[$id] .= $data; 
}
}
}
else { 
//   echo 'Timeout: ' . date('h:i:s') . "nnn";
break;
}
}

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

最新更新