Downloading files with cURL in PHP

This is a simple tutorial on how to download files with cURL in PHP.

Firstly, allow me to present you with the code (because let’s be honest, that’s what most of you came here for). The example below will download a fictional logo image via cURL. Simply change the $fileUrl and $saveTo variables to meet your requirements.

<?php

//The resource that we want to download.
$fileUrl = 'http://example.com/img/logo.png';

//The path & filename to save to.
$saveTo = 'logo.png';

//Open file handler.
$fp = fopen($saveTo, 'w+');

//If $fp is FALSE, something went wrong.
if($fp === false){
    throw new Exception('Could not open: ' . $saveTo);
}

//Create a cURL handle.
$ch = curl_init($fileUrl);

//Pass our file handle to cURL.
curl_setopt($ch, CURLOPT_FILE, $fp);

//Timeout if the file doesn't download after 20 seconds.
curl_setopt($ch, CURLOPT_TIMEOUT, 20);

//Execute the request.
curl_exec($ch);

//If there was an error, throw an Exception
if(curl_errno($ch)){
    throw new Exception(curl_error($ch));
}

//Get the HTTP status code.
$statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

//Close the cURL handler.
curl_close($ch);

//Close the file handler.
fclose($fp);

if($statusCode == 200){
    echo 'Downloaded!';
} else{
    echo "Status Code: " . $statusCode;
}

Now for the explanation!

To download a file via cURL, we need to give it a file pointer resource. We can achieve this by using the fopen function like so:

//Create file pointer
$fp = fopen($saveTo, 'w+');

On success, the fopen function will return a file pointer resource. Note that we pass in “w+” as the second parameter because “w+” tells PHP that we want to open the file for reading and writing.

After we’ve successfully set up our file pointer, we can hand it over to cURL via the CURLOPT_FILE option, like so:

//Pass our file handle to cURL.
curl_setopt($ch, CURLOPT_FILE, $fp);

This tells cURL that we want to save the transferred data of our request to the given file. Note that we also set the option CURLOPT_TIMEOUT to 20 seconds, simply because larger file sizes may result in longer request (when it comes to downloading files, we need to be weary of the possibility of timeouts):

//Timeout after 20 seconds
curl_setopt($ch, CURLOPT_TIMEOUT, 20);

As you can see, downloading a resource with cURL in PHP is not much different than sending a regular HTTP request. The only difference is that you need to give cURL a valid stream resource.

See also: Downloading files with file_get_contents.