16

I want to upload a file using cURL. Since cURL requires full path to the file so here is my code:

curl_setopt($ch, CURLOPT_POSTFIELDS, array("submit" => "submit", "file" => "@path/to/file.ext"));
curl_exec($ch);

However cURL will also post this full path of the file in the request header:

Content-Disposition: form-data; name="file"; filename="/path/to/file.ext"

But I want it to be just

Content-Disposition: form-data; name="file"; filename="file.ext"

So I change the code to

curl_setopt($ch, CURLOPT_POSTFIELDS, array("submit" => "submit", "file" => "@file.ext"));
chdir("path/to"); # change current working directory to where the file is placed
curl_exec($ch);
chdir("path"); # change current working directory back

And then cURL simply throws an error message

couldn't open file "file.ext"

Can anybody tell me how to do it please?

Teiv
  • 2,605
  • 10
  • 39
  • 48

3 Answers3

25

New method (since PHP 5.5) using CURLFile:

$file = new CURLFile('path/to/file.ext');
$file->setPostFilename('file.ext');

use it almost the same:

"file" => $file

Old method:

Instead of

"file" => "@path/to/file.ext"

you can tell cURL to use another filename:

"file" => "@path/to/file.ext; filename=file.ext"

That way it will use path/to/file.ext as file source, but file.ext as filename.

You'll need a very absolute path though, so you're probably missing a leading /: /path/to/file.ext. Since you're using PHP, always do a realpath():

"file" => '@' . realpath($pathToFile) . '; filename=' . basename($pathToFile);

Or something like that.

Rudie
  • 52,220
  • 42
  • 131
  • 173
  • Which version of PHP is required for this? – Jeroen Ooms Jan 28 '14 at 19:34
  • Any. The version of cURL might matter, but probably not. Did you try it? Try it. – Rudie Jan 28 '14 at 23:03
  • Thanks! I was looking for renaming uploaded files with the `curl` shell command and the `;filename=file.ext` suggested here works with the shell command, too. +1 – Chriki Dec 17 '14 at 10:17
  • Thank you for your great help. Just wanted to let you know that when I tried to upload file with filename it didn't worked, *I needed to remove space between parameters*. So this worked--> `@/path/to/file;filename=abc.jpg` – Ravi Dhoriya ツ Jan 24 '16 at 18:09
  • 1
    You should use the new method, using `CURLFile`, not the old method, using `@file`. You definitely should be on PHP 5.5 by now. – Rudie Jan 24 '16 at 23:49
  • @Rudie, thanks for the suggestion. I've working CURLFile on my localhost, but not yet with my hosting provider. So I put condition `function_exists('curl_file_create')` and based on that I wrote the code for `php 5.5<` and `php5.5>=` – Ravi Dhoriya ツ Jan 25 '16 at 06:22
13

Please correct me if I'm wrong but cURL upload won't work with relative path. It always need an absolute path, likes

$realpath = realpath($uploadfile);

So if someone wants to hide the location to his file on his webserver when uploading, either move it to a temporary folder or use fsockopen() (see this example in PHP Manual's User Contributed Notes)

Teiv
  • 2,605
  • 10
  • 39
  • 48
0

Your going to need to put the file in a temporary area and then reference the file from there if you want to hide the true file location. Unfortunately cURL doesn't support sending just binary data or else you could just send the base64 or binary data string instead of a filename reference.

davidethell
  • 11,708
  • 6
  • 43
  • 63