• 7
name Punditsdkoslkdosdkoskdo

How to make asynchronous HTTP demands in PHP

Is there a way in PHP to make asynchronous HTTP calls? I don't care about the response, I just want to do something like file_get_contents(), but not wait for the request to finish before executing the rest of my code. This would be super useful for setting off "events" of a sort in my application, or triggering long processes.

Any ideas?

You can do trickery by using exec() to invoke something that can do HTTP requests, like wget, but you must direct all output from the program to somewhere, like a file or /dev/null, otherwise the PHP process will wait for that output.

If you want to separate the process from the apache thread entirely, try something like (I'm not sure about this, but I hope you get the idea):

exec('bash -c "wget -O (url goes here) > /dev/null 2>&1 &"');

It's not a nice business, and you'll probably want something like a cron job invoking a heartbeat script which polls an actual database event queue to do real asynchronous events.

  • 0
Reply Report

If you control the target that you want to call asynchronously (e.g. your own "longtask.php"), you can close the connection from that end, and both scripts will run in parallel. It works like this:

  1. quick.php opens longtask.php via cURL (no magic here)
  2. longtask.php closes the connection and continues (magic!)
  3. cURL returns to quick.php when the connection is closed
  4. Both tasks continue in parallel

I have tried this, and it works just fine. But quick.php won't know anything about how longtask.php is doing, unless you create some means of communication between the processes.

Try this code in longtask.php, before you do anything else. It will close the connection, but still continue to run (and suppress any output):

while(ob_get_level()) ob_end_clean();
header('Connection: close');
echo('Connection Closed');
$size = ob_get_length();
header("Content-Length: $size");
  • 0
Reply Report
function post_without_wait($url, $params)
    foreach ($params as $key => &$val) {
      if (is_array($val)) $val = implode(',', $val);
        $post_params[] = $key.'='.urlencode($val);
    $post_string = implode('&', $post_params);


    $fp = fsockopen($parts['host'],
        $errno, $errstr, 30);

    $out = "POST ".$parts['path']." HTTP/1.1
    $out.= "Host: ".$parts['host']."
    $out.= "Content-Type: application/x-www-form-urlencoded
    $out.= "Content-Length: ".strlen($post_string)."
    $out.= "Connection: Close

    if (isset($post_string)) $out.= $post_string;

    fwrite($fp, $out);
  • 0
Reply Report