Dimitar Dimov
Dimitar Dimov

Reputation: 49

php asynchronous cURL request

I am developing a website with PHP and sending requests with cURL.

I have a website, that does some calculations, that I need to get a response from. I am sending requests via cURL Currently what I'm doing is to send a request, wait 10 sec and send it again (max 3 times), if no "good" response is received. If all request fail, I flag them for "manual fix".

The thing is I want to send a request with 30 sec timeout, and on the 10th second, if no response is received, to send another one with 20 sec timeout, on the 20th second to send last one with 10 sec timeout. Is such thing possible?

Or if my current code remains and I continue to send requests every 10th second with timeout 10 sec each, can I continue to listen to the first one after I send the second (and first and second when I'm sending the third)?

Thank you in advance!

Upvotes: 4

Views: 16240

Answers (5)

Harsh Patel
Harsh Patel

Reputation: 1324

If you wish to send asynchronous cUrl requests then we need to use curl_multi_init().

I share sample code about Simultaneous cURL requests using curl_multi_exec in PHP Foreach loop

<?php
$products = [
    [
        "name" => "test",
        "slug" => "test-product"
    ],
    [
        "name" => "test-data",
        "slug" => "test-data"
    ],
];

$adminToken = "your-api-access-token";
// array of curl handles
$multiCurl = array();
$result = array();

//create the multiple cURL handle
$mh = curl_multi_init();

$headers = ['Content-Type:application/json', 'Authorization:Bearer ' . $adminToken];
$apiUrl = $this->baseUrl . "products/create";

foreach ($products as $key => $product) {
    $productData["product"] = $product;
    $dataString = json_encode($productData);

    $multiCurl[$key] = curl_init();
    curl_setopt($multiCurl[$key], CURLOPT_URL, $apiUrl);
    curl_setopt($multiCurl[$key], CURLOPT_CUSTOMREQUEST, "POST");

    curl_setopt($multiCurl[$key], CURLOPT_POSTFIELDS, $dataString);
    curl_setopt($multiCurl[$key], CURLOPT_RETURNTRANSFER, true);
    curl_setopt($multiCurl[$key], CURLOPT_SSL_VERIFYPEER, false);
    curl_setopt($multiCurl[$key], CURLOPT_HTTPHEADER, $headers);
    curl_multi_add_handle($mh, $multiCurl[$key]);
}
$index = null;
do {
    curl_multi_exec($mh,$index);
} while($index > 0);

// get content and remove handles
foreach($multiCurl as $k => $ch) {
    $result[$k] = curl_multi_getcontent($ch);
    curl_multi_remove_handle($mh, $ch);
}
// close
curl_multi_close($mh);
return $result;

I hope this one helps to you...

Upvotes: 0

Alex G
Alex G

Reputation: 1

You can try use PHP Simple Curl Wrapper - https://github.com/Graceas/php-simple-curl-wrapper. This library allows the processing of multiple request's asynchronously.

Add requirements to composer:

"require": {
    ...
    "graceas/php-simple-curl-wrapper": "v1.5.4"
    ...
}

Initiate requests:

$requests = [
    (new \SimpleCurlWrapper\SimpleCurlRequest())
        ->setUrl('http://ip-api.com/json?r=1')
        ->setMethod(\SimpleCurlWrapper\SimpleCurlRequest::METHOD_GET)
        ->setHeaders([
            'Accept: application/json',
            'User-Agent: simple curl wrapper',
        ])
        ->setOptions([
            CURLOPT_FOLLOWLOCATION => false,
        ])
        ->setCallback('loadCallback'),
    (new \SimpleCurlWrapper\SimpleCurlRequest())
        ->setUrl('http://ip-api.com/json?r=2')
        ->setMethod(\SimpleCurlWrapper\SimpleCurlRequest::METHOD_GET)
        ->setHeaders([
            'Accept: application/json',
            'User-Agent: simple curl wrapper',
        ])
        ->setOptions([
            CURLOPT_FOLLOWLOCATION => false,
        ])
        ->setCallback('loadCallback'),
];

Initiate callback:

function loadCallback(\SimpleCurlWrapper\SimpleCurlResponse $response) {
    print_r($response->getRequest()->getUrl());
    print_r($response->getHeadersAsArray());
    print_r($response->getBodyAsJson());
}

Initiate wrapper and execute requests:

$wrapper = new \SimpleCurlWrapper\SimpleCurlWrapper();
$wrapper->setRequests($requests);
$wrapper->execute(2); // how many requests will be executed async

Upvotes: 0

BSB
BSB

Reputation: 2468

If you want to send multiple curl requests parallely, curl_multi will be helpful as below:

// create both cURL resources
$ch1 = curl_init();
$ch2 = curl_init();

// set URL and other appropriate options
curl_setopt($ch1, CURLOPT_URL, "http://lxr.php.net/");
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch2, CURLOPT_URL, "http://www.php.net/");
curl_setopt($ch2, CURLOPT_HEADER, 0);

//create the multiple cURL handle
$mh = curl_multi_init();

//add the two handles
curl_multi_add_handle($mh,$ch1);
curl_multi_add_handle($mh,$ch2);

//execute the multi handle
do {
    $status = curl_multi_exec($mh, $active);
    if ($active) {
        curl_multi_select($mh);
    }
} while ($active && $status == CURLM_OK);

//close the handles
curl_multi_remove_handle($mh, $ch1);
curl_multi_remove_handle($mh, $ch2);
curl_multi_close($mh);

You can customize this code ex. use loop for creating curl requests etc.

Ref : https://www.php.net/manual/en/function.curl-multi-init.php

Upvotes: 1

Faiz Rasool
Faiz Rasool

Reputation: 1379

Use this function

//background excute and wait for response
private function BackgroundsendPostData($url, Array $post) {
    $data = "";
    foreach ($post as $key => $row) {
        $row = urlencode($row); //fix the url encoding
        $key = urlencode($key); //fix the url encoding                
        if ($data == "") {
            $data .="$key=$row";
        } else {
            $data .="&$key=$row";
        }
    }
    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
    curl_setopt($ch, CURLOPT_TIMEOUT_MS, 2000);
    $result = curl_exec($ch);
    curl_close($ch);  // Seems like good practice
    return;
}
//usage 
BackgroundsendPostData("http://www.google.co.uk/",array('pram1'=>'value1','pram2'=>'value2'));

Upvotes: -2

Praveen D
Praveen D

Reputation: 2377

Use blow to make async curl call

    curl_setopt($crl, CURLOPT_TIMEOUT, 1);
    curl_setopt($crl, CURLOPT_NOSIGNAL, 1);

PHP SetOpt

Upvotes: 9

Related Questions