98

How can I upload a file, either by using cURL or anything else, in PHP?

In other words, the user sees a file upload button on a form, the form gets posted to my PHO script, then my PHP script needs to re-post it to another script (eg on another server).

I have this code to receive the file and upload it:

echo"".$_FILES['userfile']."";
$uploaddir = './';
$uploadfile = $uploaddir . basename($_FILES['userfile']['name']);
if ( isset($_FILES["userfile"]) ) {
    echo '<p><font color="#00FF00" size="7">Uploaded</font></p>';
    if (move_uploaded_file
($_FILES["userfile"]["tmp_name"], $uploadfile))
echo $uploadfile;
    else echo '<p><font color="#FF0000" size="7">Failed</font></p>';
}

How can I send the file to the receiver server?

Cristik
  • 30,989
  • 25
  • 91
  • 127
Hadidi44
  • 1,007
  • 2
  • 9
  • 7

2 Answers2

188

Use:

if (function_exists('curl_file_create')) { // php 5.5+
  $cFile = curl_file_create($file_name_with_full_path);
} else { // 
  $cFile = '@' . realpath($file_name_with_full_path);
}
$post = array('extra_info' => '123456','file_contents'=> $cFile);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$target_url);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
$result=curl_exec ($ch);
curl_close ($ch);

You can also refer:

http://blog.derakkilgo.com/2009/06/07/send-a-file-via-post-with-curl-and-php/

Important hint for PHP 5.5+:

Now we should use https://wiki.php.net/rfc/curl-file-upload but if you still want to use this deprecated approach then you need to set curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);

robsch
  • 9,358
  • 9
  • 63
  • 104
karthik
  • 2,014
  • 1
  • 13
  • 5
  • thanks but how to upload it in different name like the file name is x.php and i want to upload it with z.php name – Hadidi44 Mar 04 '13 at 12:03
  • In the about example "sample" is the name. you can access the data using $_FILES['sample'] so you can pass x.php and retrieve using $_FILES['x'] – karthik Mar 04 '13 at 12:18
  • 9
    Maybe, is a better way use the built-in feature from curl: http://www.php.net/manual/es/function.curl-file-create.php. Of course, you can use the way of POSTFIELDS and fill the value prepending with `@`. Anyway, the asnwer is copied from a custom usage of curl from a blog. The correct answer is say that the `@` char defines it as a file, not a var. $post will contain `@filename.jpg` by example. – m3nda Nov 09 '13 at 23:26
  • 2
    @erm3nda That's PHP 5.5+ only. – Jeremy Logan Jun 19 '14 at 21:16
  • 10
    @fiXedd im currently using php 5.6, and using `curl_file_create` is required (the sollution provided by karthik is not working). So the code should be upgraded to something like this: `if function_exists('curl_file_create')) { $cFile = curl_file_create($dest); } else { $cFile = '@' . realpath($dest); }` – Marek Roj Sep 15 '14 at 17:29
  • Now we should use https://wiki.php.net/rfc/curl-file-upload but if you still want to use this deprecated approach then you need to set curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false); – Alan H Dec 18 '14 at 10:28
  • 4
    What is `extra_info => 123456` used for? – Aaron Gillion Apr 26 '15 at 01:24
  • 3
    this solution stopped working in php 5.6, the solution is in adding file as: new CURLFile(realpath($fileName)); – Michał Fraś Feb 29 '16 at 10:45
  • @MarekRoj You make my day – serghei Apr 24 '16 at 15:10
  • CURLOPT_SAFE_UPLOAD is not supported for php7 – gouchaoer Jan 09 '17 at 07:03
  • `but if you still want to use this deprecated approach then you need to set curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);` - this won't work as of PHP 7.0 – hanshenrik Feb 02 '19 at 20:31
  • This code though, I can't get file content – Pooja Jadav May 20 '19 at 08:23
  • The RFC should be the answer for it. Thanks for providing clue here. – Benyamin Limanto Aug 16 '19 at 03:55
4

For those using php >= 5.5, CURLFile can be used:

$curlFile = new \CURLFile('test.txt', 'text/plain', 'test.txt');

$ch = curl_init('http://example.com/upload.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
    'file' => $curlFile,
]);

$result = curl_exec($ch);

if ($result === false) {
    echo 'upload - FAILED' . PHP_EOL;
}

From php 8.1, the file can only reside in memory if desired using CURLStringFile:

$txt_curlfile = new \CURLStringFile('test content', 'test.txt', 'text/plain');

$ch = curl_init('http://example.com/upload.php');
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, [
    'file' => $txt_curlfile
]);

$result = curl_exec($ch);

if ($result === false) {
    echo 'upload - FAILED' . PHP_EOL;
}

Reference: https://php.watch/versions/8.1/CURLStringFile

8ctopus
  • 2,617
  • 2
  • 18
  • 25