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):
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.
Here is my own PHP function when I do POST to a specific URL of any page.... Sample: *** usage of my Function...
Well, the timeout can be set in milliseconds, see "CURLOPT_CONNECTTIMEOUT_MS" in http://www.php.net/manual/en/function.curl-setopt
Event Extension
Event extension is very appropriate. It is a port of Libevent library which is designed for event-driven I/O, mainly for networking.
I have written a sample HTTP client that allows to schedule a number of HTTP requests and run them asynchronously.
This is a sample HTTP client class based on Event extension.
The class allows to schedule a number of HTTP requests, then run them asynchronously.
http-client.php
test.php
This is a sample script on the server side.
Usage
Sample Output
(Trimmed.)
Note, the code is designed for long-term processing in the CLI SAPI.
For custom protocols, consider using low-level API, i.e. buffer events, buffers. For SSL/TLS communications, I would recommend the low-level API in conjunction with Event's ssl context. Examples:
Although Libevent's HTTP API is simple, it is not as flexible as buffer events. For example, the HTTP API currently doesn't support custom HTTP methods. But it is possible to implement virtually any protocol using the low-level API.
Ev Extension
I have also written a sample of another HTTP client using Ev extension with sockets in non-blocking mode. The code is slightly more verbose than the sample based on Event, because Ev is a general purpose event loop. It doesn't provide network-specific functions, but its
EvIo
watcher is capable of listening to a file descriptor encapsulated into the socket resource, in particular.This is a sample HTTP client based on Ev extension.
Ev extension implements a simple yet powerful general purpose event loop. It doesn't provide network-specific watchers, but its I/O watcher can be used for asynchronous processing of sockets.
The following code shows how HTTP requests can be scheduled for parallel processing.
http-client.php
Testing
Suppose
http://my-host.local/test.php
script is printing the dump of$_GET
:Then the output of
php http-client.php
command will be similar to the following:(trimmed)
Note, in PHP 5 the sockets extension may log warnings for
EINPROGRESS
,EAGAIN
, andEWOULDBLOCK
errno
values. It is possible to turn off the logs withConcerning "the Rest" of the Code
The code that is supposed to run in parallel with the network requests can be executed within a the callback of an Event timer, or Ev's idle watcher, for instance. You can easily figure it out by watching the samples mentioned above. Otherwise, I'll add another example :)