PHP: Upload a file using cURL.

This is a short tutorial on how to upload a file using PHP’s cURL extension.

The goal of this is to obviously use PHP to mimic an upload form.

Let’s get started!

Take a look at the following example, which we have heavily commented:

//The URL that accepts the file upload.
$url = 'http://example.com/upload';

//The name of the field for the uploaded file.
$uploadFieldName = 'user_file';

//The full path to the file that you want to upload
$filePath = '/path/to/file.csv';


//Initiate cURL
$ch = curl_init();

//Set the URL
curl_setopt($ch, CURLOPT_URL, $url);

//Set the HTTP request to POST
curl_setopt($ch, CURLOPT_POST, true);

//Tell cURL to return the output as a string.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

//If the function curl_file_create exists
if(function_exists('curl_file_create')){
    //Use the recommended way, creating a CURLFile object.
    $filePath = curl_file_create($filePath);
} else{
    //Otherwise, do it the old way.
    //Get the canonicalized pathname of our file and prepend
    //the @ character.
    $filePath = '@' . realpath($filePath);
    //Turn off SAFE UPLOAD so that it accepts files
    //starting with an @
    curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);
}

//Setup our POST fields
$postFields = array(
    $uploadFieldName => $filePath,
    'blahblah' => 'Another POST FIELD'
);

curl_setopt($ch, CURLOPT_POSTFIELDS, $postFields);

//Execute the request
$result = curl_exec($ch);

//If an error occured, throw an exception
//with the error message.
if(curl_errno($ch)){
    throw new Exception(curl_error($ch));
}

//Print out the response from the page
echo $result;

As you’ve probably realized, the PHP script above is pretty easy to customize. We have intentionally put three key variables at the top of the script:

  • $url: This is the HTTP URL that you want to upload your file to.
  • $uploadFieldName: This is the name of the POST field that will contain the file that you want cURL to upload.
  • Finally, we have $filepath, which should contain the full path to the file in question.

As a result, this PHP script will pretty much work “straight off the shelf” as long as you change those three variables to suit your own needs. The only section that you might need to customize besides those variables is the $postFields array on line 38. The $postFields array represents our POST keys and values.

How does this cURL upload script work?

If you are looking for a more in-depth explanation of how this script works, be sure to read on.

Initializing.

We initialized our important variables at the top of the script. These define the file we’re uploading, the URL that we want to upload to, and the name of the POST field that should contain the file.

We then initialized cURL using curl_init, set the HTTP request type to POST, and told cURL to return the response as a string instead of just dumping it out onto the page.

Using curl_file_exists.

If the function curl_file_create exists, we presume that the server is using PHP 5.5 or above. This is because curl_file_create was only introduced to PHP in version 5.5.

Using the function curl_file_create to create a CURLFile object that represents our file is the recommended way of uploading a file with cURL. If the function exists, you should use it.

If curl_file_exists does not exist.

However, if curl_file_create does not exist, then we attempt to use the old deprecated approach. In this case, we use a canonicalized path to the file that has the @ character appended. Note that the @ (at) character in this case is not used to suppress PHP error messages.

If you look closely at the code above, you will see that the @ symbol has actually been appended as part of the string. i.e. It is a part of the file path. This symbol tells cURL that it is a file name and that it should post the data without any extra processing.

If we are using the older method of uploading files with cURL, we also have to make sure that we disable the CURLOPT_SAFE_UPLOAD option. This is so that it will accept the @ character as the start of a file name.

Attaching our POST fields.

On line 38, we created our post fields array. As you can see, we attached the file path to the field name that it will have during the POST request. In the code above, we have set this field name to user_file. This means that the POST variable user_file will contain the file that we want to upload.

We also attached a second POST parameter called blahblah. You can obviously remove this, as its only purpose is to show readers that they can add additional POST fields. For example, you might need to provide an ID field, etc.

Executing the POST request.

Finally, we told cURL to execute the POST request and upload our file. We also added some error handling so that cURL will throw an Exception if the request fails.

If the request is successful, you should see a response from the server.

Related: Send a PUT request with PHP’s cURL functions.