Ben G
Ben G

Reputation: 26791

cURL retry in PHP

Is it possible to set the option to retry on timeouts in PHP cURL?

I know I can do this by coding it to retry on failure, just wondering if there's some way to do it through an option.

Upvotes: 17

Views: 24086

Answers (3)

Eboubaker
Eboubaker

Reputation: 800

I was trying to make my file download function be resumable, here's what i've come up with. using fstat() to get what was downloaded and feed that value to curl on failure using the CURLOPT_RESUME_FROM option.

function download_file(string $url): ?string
{
    $name = tempnam(sys_get_temp_dir(), time() . ".tmp");
    $out = fopen($name, 'a+');
    start_over:
    {
        $ch = curl_init();
        curl_setopt($ch, CURLOPT_HTTPHEADER, Utils::make_curl_headers());
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_TIMEOUT, 0);

        // TODO: SSL
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);

        curl_setopt($ch, CURLOPT_FILE, $out);
        curl_setopt($ch, CURLOPT_RESUME_FROM, fstat($out)['size']);
        curl_setopt($ch, CURLOPT_HEADER, false);
        curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
        curl_setopt($ch, CURLOPT_MAXREDIRS, 5);

        curl_setopt($ch, CURLOPT_NOPROGRESS, false);

        curl_setopt($ch, CURLOPT_PROGRESSFUNCTION, $delayed_progress);
        curl_setopt($ch, CURLOPT_BUFFERSIZE, bytes("64kb"));
        curl_exec($ch);
        curl_close($ch);

        if (curl_errno($ch) !== 0) {
            fwrite(STDOUT, "  ERROR: " . (curl_error($ch) ?? "CONNECTION_ERROR") 
              . ", will try again in 10 seconds..." . PHP_EOL);
            sleep(10);
            goto start_over;
        }
    }
    return $name;
}

Upvotes: 0

Cyrec
Cyrec

Reputation: 455

you can use the errno to retry like this:

$curl = curl_init();
curl_setopt_array($curl, $options);
$response = curl_exec($curl);
$retry = 0;
while(curl_errno($curl) == 28 && $retry < 3){
    $response = curl_exec($curl);
    $retry++;
}

$error_codes=array(
    [1] => 'CURLE_UNSUPPORTED_PROTOCOL', 
    [2] => 'CURLE_FAILED_INIT', 
    [3] => 'CURLE_URL_MALFORMAT', 
    [4] => 'CURLE_URL_MALFORMAT_USER', 
    [5] => 'CURLE_COULDNT_RESOLVE_PROXY', 
    [6] => 'CURLE_COULDNT_RESOLVE_HOST', 
    [7] => 'CURLE_COULDNT_CONNECT', 
    [8] => 'CURLE_FTP_WEIRD_SERVER_REPLY',
    [9] => 'CURLE_REMOTE_ACCESS_DENIED',
    [11] => 'CURLE_FTP_WEIRD_PASS_REPLY',
    [13] => 'CURLE_FTP_WEIRD_PASV_REPLY',
    [14]=>'CURLE_FTP_WEIRD_227_FORMAT',
    [15] => 'CURLE_FTP_CANT_GET_HOST',
    [17] => 'CURLE_FTP_COULDNT_SET_TYPE',
    [18] => 'CURLE_PARTIAL_FILE',
    [19] => 'CURLE_FTP_COULDNT_RETR_FILE',
    [21] => 'CURLE_QUOTE_ERROR',
    [22] => 'CURLE_HTTP_RETURNED_ERROR',
    [23] => 'CURLE_WRITE_ERROR',
    [25] => 'CURLE_UPLOAD_FAILED',
    [26] => 'CURLE_READ_ERROR',
    [27] => 'CURLE_OUT_OF_MEMORY',
    [28] => 'CURLE_OPERATION_TIMEDOUT',
    ....

Upvotes: 30

Femi
Femi

Reputation: 64700

Not with the current options available to the PHP cURL extension. On the command line I believe there is the --retry option, but that is not exposed to PHP.

Upvotes: 7

Related Questions