How to send asynchronous requests in PHP


It’s easy to make asynchronous calls in PHP with just a little bit of HTTP header knowledge and some library code around PHP sockets.

This technique is useful when posting requests to your own server for bits of logic you’d like to run in the background.  If you don’t control the endpoint, you might not be comfortable with some of the limitations, such as the inability to read anything from the response.  So, you couldn’t post data to a webservice and receive an HTTP 200 OK response and certainly not an ID for an object newly created by the service call. Any bad IP address would give you an error and you’d also get an error if your socket couldn’t connect. This level of error handling might be sufficient for what you need.

For best performance, use IP addresses instead of DNS entries to prevent the need for look-up and resolution.

For fire and forget stuff, this is the bees knees:

(Please ignore my class definition and Controller superclass. This is actual working code from my CodeIgniter application where I scratched this out as a proof of concept)

class Scratch extends SQ_Controller {

    function Scratch() {
        parent::SQ_Controller();
    }

    function index() {

        echo "PHP Async Test...
";

        $params = array(
            "one" => "111111",
            "two" => "22222",
            "three" => "33333",
            "four" => "44444",
        );
        $this->curl_post_async("http://127.0.0.1/sq/scratch/longone", $params);
    }

    function longone(){

        $one = $_POST["one"];
        $two = $_POST["two"];
        $three = $_POST["three"];
        $four = $_POST["four"];

        echo uniqid("You won't see this because your PHP script isn't waiting to read any response");

        // put some long delay in here, so you can see how quickly the async requests returns
        sleep(5);

        // and the proof that something actually happens...  write out the HTTP params that were sent over the wire
        $fp = fopen('/PATH/TO/YOUR/DIR/FOR/OUTPUT/data.txt', 'w');
        fwrite($fp, $one);
        fwrite($fp, $two);
        fwrite($fp, $three);
        fwrite($fp, $four);
        fclose($fp);

    }

    function curl_post_async($url, $params = array()){

        $post_params = array();

        foreach ($params as $key => &$val) {
              if (is_array($val)) $val = implode(',', $val);
                $post_params[] = $key.'='.urlencode($val);
            }
            $post_string = implode('&', $post_params);

            $parts=parse_url($url);

            $fp = fsockopen($parts['host'],
                isset($parts['port'])?$parts['port']:80,
                $errno, $errstr, 30);

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

            fwrite($fp, $out);
            fclose($fp);
    }
}
Copy from http://blog.markturansky.com/archives/205
Advertisements
By dbglory Posted in PHP

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s