4

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!

5 Answers 5

9

Use blow to make async curl call

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

PHP SetOpt

Sign up to request clarification or add additional context in comments.

5 Comments

CURLOPT_TIMEOUT 1 will close the request instantly and the actually url script would not run. I have tried that yesterday.
It will send request and wont wait for response. It works for me.
Yes i tried many variations and finally i found at least give 2 second time out. which is 2000. Anyway it solve the problem let me vote up :)
You can add and try curl_setopt($ch, CURLOPT_TIMEOUT_MS, 2000);
That's what I'm currently using and it's working alright. The thing is I want to continue to listen to the request even if the timeout time has passed (e.g. 10s). Is this possible?
1

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

Comments

0

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

2 Comments

This doesn't answer the question: how to change the timeout for each request
you can change timeout for every request: (new \SimpleCurlWrapper\SimpleCurlRequest())->setOptions(array(CURLOPT_TIMEOUT => 5))
0

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...

Comments

-2

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'));

1 Comment

You have added CURLOPT_FOLLOWLOCATION twice and what does this function make to run in background ? Is there any ?

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.