HttpRequestPool类提供了解决方案。非常感谢那些指出这一点的人。
可在以下网址找到简要教程:http://www.phptutorial.info/?HttpRequestPool-construct
问题
我想在PHP中进行并发/并行/同步HTTP请求。我想避免连续请求:
我设法找到制作simultaneuos [sic] HTTP requests in PHP with cURL的详细信息,但是如果可能的话,我想明确使用PHP的HTTP functions。
具体来说,我需要将数据同时发送到一组URL。发布数据的网址超出了我的控制范围;它们是用户设置的。
我不介意在处理回复之前是否需要等待所有请求完成。如果我在每个请求上设置30秒的超时并同时发出请求,我知道我必须等待最多30秒(可能多一点)才能完成所有请求。
我找不到如何实现这一目标的细节。但是,我最近注意到在PHP手册中提到PHP5 +能够处理并发HTTP请求 - 我打算在当时记下它,忘记了,再也找不到了。
单个请求示例(正常工作)
<?php
$request_1 = new HttpRequest($url_1, HTTP_METH_POST);
$request_1->setRawPostData($dataSet_1);
$request_1->send();
?>
并发请求示例(不完整,清楚)
<?php
$request_1 = new HttpRequest($url_1, HTTP_METH_POST);
$request_1->setRawPostData($dataSet_1);
$request_2 = new HttpRequest($url_2, HTTP_METH_POST);
$request_2->setRawPostData($dataSet_2);
// ...
$request_N = new HttpRequest($url_N, HTTP_METH_POST);
$request_N->setRawPostData($dataSet_N);
// Do something to send() all requests at the same time
?>
任何想法都会非常感激!
澄清1 :我想坚持PECL HTTP功能:
澄清2 :我意识到PHP的HTTP功能没有内置,也许我在那里措辞错误,我会纠正。我不担心人们不得不安装额外的东西 - 这不是一个要分发的应用程序,它是一个带有服务器的Web应用程序。
澄清3 :如果某人权威地声明PECL HTTP无法做到这一点,我会非常高兴。
答案 0 :(得分:10)
我很确定HttpRequestPool正是您所寻找的。 p>
为了详细说明,您可以使用分叉来实现您正在寻找的东西,但这似乎不必要地复杂并且在HTML上下文中不是很有用。虽然我没有测试过,但这段代码应该是它:
// let $requests be an array of requests to send $pool = new HttpRequestPool(); foreach ($requests as $request) { $pool->attach($request); } $pool->send(); foreach ($pool as $request) { // do stuff }
答案 1 :(得分:2)
你试过HttpRequestPool(这是Http的一部分)吗?看起来它会汇集请求对象并进行处理。我知道我读过Http支持同时请求的地方除了 pool 之外我也找不到任何东西。
答案 2 :(得分:2)
我曾经不得不解决类似的问题:在不累积响应时间的情况下执行多个请求。
该解决方案最终成为使用非阻塞sockets的自定义构建函数。 它的工作原理如下:
$request_list = array(
# address => http request string
#
'127.0.0.1' => "HTTP/1.1 GET /index.html\nServer: website.com\n\n",
'192.169.2.3' => "HTTP/1.1 POST /form.dat\nForm-data: ...",
);
foreach($request_list as $addr => $http_request) {
# first, create a socket and fire request to every host
$socklist[$addr] = socket_create();
socket_set_nonblock($socklist[$addr]); # Make operation asynchronious
if (! socket_connect($socklist[$addr], $addr, 80))
trigger_error("Cannot connect to remote address");
# the http header is send to this host
socket_send($socklist[$addr], $http_request, strlen($http_request), MSG_EOF);
}
$results = array();
foreach(array_keys($socklist) as $host_ip) {
# Now loop and read every socket until it is exhausted
$str = socket_read($socklist[$host_ip], 512, PHP_NORMAL_READ);
if ($str != "")
# add to previous string
$result[$host_ip] .= $str;
else
# Done reading this socket, close it
socket_close($socklist[$host_ip]);
}
# $results now contains an array with the full response (including http-headers)
# of every connected host.
由于thunked响应以半并行方式获取,所以速度要快得多,因为socket_read不会等待响应,但如果套接字缓冲区尚未满,则会返回。
您可以将其包装在适当的OOP界面中。您将需要自己创建HTTP请求字符串,并且当然要处理服务器响应。
答案 3 :(得分:1)
一位朋友最近向我指出了CurlObjects(http://trac.curlobjects.com/trac),我觉得这对使用curl_multi非常有用。
$curlbase = new CurlBase;
$curlbase->defaultOptions[ CURLOPT_TIMEOUT ] = 30;
$curlbase->add( new HttpPost($url, array('name'=> 'value', 'a' => 'b')));
$curlbase->add( new HttpPost($url2, array('name'=> 'value', 'a' => 'b')));
$curlbase->add( new HttpPost($url3, array('name'=> 'value', 'a' => 'b')));
$curlbase->perform();
foreach($curlbase->requests as $request) {
...
}
答案 4 :(得分:0)
PHP的HTTP函数aren't built in,它们都是PECL扩展。如果你担心的是人们不得不安装额外的东西,那么这两个解决方案都会遇到同样的问题 - 而且我认为cURL更有可能被安装,因为它默认为我曾经使用的每个网络主机。
答案 5 :(得分:-1)
您可以使用pcntl_fork()为每个请求创建一个单独的进程,然后等待它们结束:
http://www.php.net/manual/en/function.pcntl-fork.php
你有什么理由不想使用cURL吗? curl_multi_ *函数可以同时允许多个请求。