Parallel HTTP requests in PHP using PECL HTTP classes [Answer: HttpRequestPool class]

自闭症网瘾萝莉.ら 提交于 2019-11-28 21:34:48

I'm pretty sure HttpRequestPool is what you're looking for.

To elaborate a little, you can use forking to achieve what you're looking for, but that seems unnecessarily complex and not very useful in a HTML context. While I haven't tested, this code should be it:

// 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
}

Did you try HttpRequestPool (it's part of Http)? It looks like it would pool up the request objects and work them. I know I read somewhere that Http would support simultaneous requests and aside from pool I can't find anything either.

I once had to solve similar problem: doing multiple requests without cumulating the response times.

The solution ended up being a custom-build function which used non-blocking sockets. It works something like this:

$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.

It's much faster since thunked reponses are fetched in semi-parallel since socket_read doesn't wait for the response but returns if the socket-buffer isn't full yet.

You can wrap this in appropriate OOP interfaces. You will need to create the HTTP-request string yourself, and process the server response of course.

A friend pointed me to CurlObjects ( http://trac.curlobjects.com/trac ) recently, which I found quite useful for using 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) { ... }

PHP's HTTP functions aren't built in, either - they're a PECL extension. If your concern is people having to install extra stuff, both solutions will have the same problem - and cURL is more likely to be installed, I'd imagine, as it comes default with every web host I've ever been on.

You could use pcntl_fork() to create a separate process for each request, then wait for them to end:

http://www.php.net/manual/en/function.pcntl-fork.php

Is there any reason you don't want to use cURL? The curl_multi_* functions would allow for multiple requests at the same time.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!