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

前端 未结 6 2195
生来不讨喜
生来不讨喜 2020-12-14 22:57

The HttpRequestPool class provides a solution. Many thanks to those who pointed this out.

A brief tutorial can be found at: http://www.phptutorial.i

相关标签:
6条回答
  • 2020-12-14 23:39

    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.

    0 讨论(0)
  • 2020-12-14 23:55

    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.

    0 讨论(0)
  • 2020-12-14 23:57

    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.

    0 讨论(0)
  • 2020-12-14 23:59

    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
    }
    
    0 讨论(0)
  • 2020-12-14 23:59

    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) { ... }

    0 讨论(0)
  • 2020-12-15 00:01

    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.

    0 讨论(0)
提交回复
热议问题