Async curl request in PHP
So what you want to do is asynchronous execution of the cUrl Requests.
So you would need a asynchronous/parallel processing library for php.
Async cURL
The other way is to use the built in asynchronous cURL functions.
So, when using curl_multi_*
, your code would look something like:
$username = 'xxxxx';
$api_onfleet = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$url_onfleet = "https://onfleet.com/api/v2/tasks";
curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
$request = $url.'api/mail.send.json';
// Generate curl request
$session = curl_init($request);
// Tell curl to use HTTP POST
curl_setopt ($session, CURLOPT_POST, true);
// Tell curl that this is the body of the POST
curl_setopt ($session, CURLOPT_POSTFIELDS, $params);
// Tell curl not to return headers, but do return the response
curl_setopt($session, CURLOPT_HEADER, false);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
// Post the Pickup task to Onfleet
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url_onfleet);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERPWD, $api_onfleet);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"destination":{"address":{"unparsed":"'.$pickup_address.'"},"notes":"'.$comments.'"},"recipients":[{"name":"'.$name.'","phone":"+61'.$phone.'","notes":"Number of riders: '.$riders.'"}],"completeBefore":'.$timestamp.',"pickupTask":"yes","autoAssign":{"mode":"distance"}}');
$mh = curl_multi_init();
curl_multi_add_handle($mh,$session);
curl_multi_add_handle($mh,$ch);
$active = null;
//execute the handles
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
while ($active && $mrc == CURLM_OK) {
if (curl_multi_select($mh) != -1) {
do {
$mrc = curl_multi_exec($mh, $active);
} while ($mrc == CURLM_CALL_MULTI_PERFORM);
}
}
//close the handles
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);
Suggested Reading:
curl_multi_init()
curl_multi_exec()
curl_multi_add_handle()
curl_multi_remove_handle()
pThreads
One of the prominent threading libraries for php is pthreads
You would need to first get the dll/so file and save it in the php/ext
dir, and enable that extension in php.ini
.
After That, this code would do your job:
class Request1 extends Thread {
$username = 'xxxxx';
$api_onfleet = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$url_onfleet = "https://onfleet.com/api/v2/tasks";
public function run() {
curl_setopt($curl, CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2);
$request = $this->url.'api/mail.send.json';
// Generate curl request
$session = curl_init($request);
// Tell curl to use HTTP POST
curl_setopt ($session, CURLOPT_POST, true);
// Tell curl that this is the body of the POST
curl_setopt ($session, CURLOPT_POSTFIELDS, $params);
// Tell curl not to return headers, but do return the response
curl_setopt($session, CURLOPT_HEADER, false);
curl_setopt($session, CURLOPT_RETURNTRANSFER, true);
// obtain response
$response = curl_exec($session);
curl_close($session);
}
}
class Request2 extends Thread {
$username = 'xxxxx';
$api_onfleet = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
$url_onfleet = "https://onfleet.com/api/v2/tasks";
public function run() {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url_onfleet);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_USERPWD, $this->api_onfleet);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_ENCODING, "");
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, '{"destination":{"address":{"unparsed":"'.$pickup_address.'"},"notes":"'.$comments.'"},"recipients":[{"name":"'.$name.'","phone":"+61'.$phone.'","notes":"Number of riders: '.$riders.'"}],"completeBefore":'.$timestamp.',"pickupTask":"yes","autoAssign":{"mode":"distance"}}');
$result_pickup = curl_exec($ch);
curl_close($ch);
// Post the Dropoff task to Onfleet
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $this->url_onfleet);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_USERPWD, $this->api_onfleet);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_ENCODING, "");
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, '{"destination":{"address":{"unparsed":"'.$dropoff_address.'"},"notes":"'.$comments.'"},"recipients":[{"name":"'.$name.'","phone":"+61'.$phone.'","notes":"Number of riders: '.$riders.'"}],"autoAssign":{"mode":"distance"}}');
$result_dropoff = curl_exec($curl);
curl_close($curl);
}
}
$req1 = new Request1();
$req1->start();
$req2 = new Request2();
$req2->start();
So, basically you need to create a class which extends the Thread
class and everything you want to run asynchronously (rather parallely), would be put in the function run()
of the class.
When you want to start the thread just instantiate the class in a variable, and call the start method of the object, like $threadsObject->start()
and everything in the run()
would be executed on another thread.
Reference:
class::Thread
Thread::start
That's it.
Is making asynchronous HTTP requests possible with PHP?
Yes.
There is the multirequest PHP library (or see: archived Google Code project). It's a multi-threaded CURL library.
As another solution, you could write a script that does that in a language that supports threading, like Ruby or Python. Then, just call the script with PHP. Seems rather simple.
This is ASYNC REQUEST. Can you help me change to Curl in php?
You can try below code :
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'https://api.offertest.net/offertest?async=true');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, "{\"userid\":\"oeAuUNreRW6cypwJpcgnlQ\", \"country\":\"us\", \"url\":\"http://www.google.com/\",\"platform\": \"android\", \"callback\":\"http://{YOURAPIURL}/offertest/{YOURCAMPAIGNID}/result\"}");
curl_setopt($ch, CURLOPT_POST, 1);
$headers = array();
$headers[] = 'Authorization: Bearer eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJvZUF1VU5yZVJXNmN5cHdKcGNnbmxRIiwiaWF0IjoxNTUxOTMxNzU3LCJqdGkiOiJUanNUaF9sUkY4MUR0VER5aWQ3bG9BIn0.DLgPiNNDHJMZTufUHS5nYTD_j3ImvxIfhMNrqlcl4LA';
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$result = curl_exec($ch);
if (curl_errno($ch)) {
echo 'Error:' . curl_error($ch);
}
curl_close ($ch);
PHP waiting for curl to finish before returning
The reason this does not work is, that PHP curl calls are always synchronous and your timeout is set to 30 seconds, which far exceeds the max. 3 seconds that is allowed for Slash commands.
But there is a fix to make this work. You just need these small changes:
Set the curl timeout to a smaller value to ensure your first script is completing below the 3 second threshold, e.g. set
CURLOPT_TIMEOUT_MS
to 400, which defines a timeout of 400 ms.Set
CURLOPT_NOSIGNAL
to 1 in your first script. This is required for the timeout to work in UNIX based systems.Make sure to ignore timeout-errors (CURL ERROR 28) in your first script, since your curl should always return a timeout error.
Make sure your second script is not aborted by the forced timeout by adding this line:
ignore_user_abort(true);
See also this answer for a full example.
P.S.: You to not need any buffer flushing for this approach.
Asynchronous cURL using POST
You'll need to create a new curl handle for every request, and then register it with http://www.php.net/manual/en/function.curl-multi-add-handle.php
here is some code i ripped out and adapted from my code base, have in mind that you should add error checking in there.
function CreateHandle($url , $data) {
$curlHandle = curl_init($url);
$defaultOptions = array (
CURLOPT_COOKIEJAR => 'cookies.txt' ,
CURLOPT_COOKIEFILE => 'cookies.txt' ,
CURLOPT_ENCODING => "gzip" ,
CURLOPT_FOLLOWLOCATION => true ,
CURLOPT_RETURNTRANSFER => true ,
CURLOPT_POST => 1,
CURLOPT_POSTFIELDS => $data
);
curl_setopt_array($curlHandle , $defaultOptions);
return $curlHandle;
}
function MultiRequests($urls , $data) {
$curlMultiHandle = curl_multi_init();
$curlHandles = array();
$responses = array();
foreach($urls as $id => $url) {
$curlHandles[$id] = CreateHandle($url , $data[$id]);
curl_multi_add_handle($curlMultiHandle, $curlHandles[$id]);
}
$running = null;
do {
curl_multi_exec($curlMultiHandle, $running);
} while($running > 0);
foreach($curlHandles as $id => $handle) {
$responses[$id] = curl_multi_getcontent($handle);
curl_multi_remove_handle($curlMultiHandle, $handle);
}
curl_multi_close($curlMultiHandle);
return $responses;
}
Related Topics
Including a Remote File in PHP
Remove the Last Character from a String
Accurate Way to Measure Execution Times of PHP Scripts
: Operator (The 'Elvis Operator') in PHP
MySQL Datetime Fields and Daylight Savings Time - How to Reference the "Extra" Hour
Lamp: How to Create .Zip of Large Files For the User on the Fly, Without Disk/Cpu Thrashing
Get Data from Json File With PHP
How to Find Out Where a Function Is Defined
Is PHP Compiled or Interpreted
How to Give PHP Write Access to a Directory
Opening/Closing Tags & Performance
Implode an Array With ", " and Add "And " Before the Last Item
Http Headers For File Downloads
How to Add a PHP Page to Wordpress
Rest API - Why Use Put Delete Post Get