6

I have the following command, which uses the --form/--F option, which I know to be working:

curl  --form "file=@/home/USERNAME/import.csv" https://apiprovider.com/api/v0/imports\?token\=[KEY]

I need to run this command via php, but I'm having trouble, presumably with the form file data. I tried the following, however echoing or var_dumping the result seems to show nothing, just a blank page or a blank string.

<?php 
$target_url = 'https://apiprovider.com/api/v0/imports?token=[KEY]'
$file_name_with_full_path ='/home/USERNAME/import.csv';
$post = array('file'=>'@'.$file_name_with_full_path);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$target_url);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_VERBOSE,true);
$result=curl_exec ($ch);
curl_close ($ch);
var_dump($result);?>

How can I get this command working in PHP?

KinsDotNet
  • 1,500
  • 5
  • 25
  • 53
  • 4
    Possible duplicate https://stackoverflow.com/questions/15200632/how-to-upload-file-using-curl-with-php – Kisaragi Oct 17 '17 at 15:23
  • Possible duplicate of [PHP + curl, HTTP POST sample code?](https://stackoverflow.com/questions/2138527/php-curl-http-post-sample-code) – teeyo Oct 17 '17 at 15:24
  • Possible duplicate of [How to convert curl file post from command line into PHP cURL](https://stackoverflow.com/questions/17865817) – Jo. Oct 19 '17 at 22:12

7 Answers7

15

since no answer got it right thus far (at least not with an approach that would work in php 5.6+), here goes: the equivalent php curl_ code would be:

$ch = curl_init ( 'https://apiprovider.com/api/v0/imports?token=[KEY]' );
curl_setopt_array ( $ch, array (
        CURLOPT_POST => 1,
        CURLOPT_POSTFIELDS => array (
                'file' => new CURLFile ( '/home/USERNAME/import.csv' ) 
        ) 
) );
curl_exec ( $ch );

(i would also recommend setting CURLOPT_ENCODING to emptystring, especially if you expect the response to be compressible, that would be the equivalent of adding --compressed to the curl command line, and might speed things up)

hanshenrik
  • 19,904
  • 4
  • 43
  • 89
4

try this:

<?php 
$target_url = 'https://apiprovider.com/api/v0/imports?token=[KEY]'
$file_name_with_full_path ='/home/USERNAME/import.csv';
$post = array('file'=>'@'.$file_name_with_full_path);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$target_url);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_VERBOSE,true);
$result = curl_exec ($ch);

$curlresponse = json_decode($result, true);

var_dump($curlresponse);
?>
jelle woord
  • 193
  • 2
  • 16
3

One way is to use CURLFile instead of @ for PHP version above 5.5

$target_url = 'https://apiprovider.com/api/v0/imports?token=[KEY]'
$file_name_with_full_path ='/home/USERNAME/import.csv';
// Create a CURLFile object
$cfile = new CURLFile($file_name_with_full_path,mime_content_type($file_name_with_full_path),'imported_csv');    
// Assign POST data
$post = array('imported_csv_file' => $cfile);    
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$target_url);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_VERBOSE,true);
$result=curl_exec ($ch);
curl_close ($ch);
var_dump($result);
1

Maybe something like this could work:

<?php 
$target_url = 'https://apiprovider.com/api/v0/imports?token=[KEY]'
$file_name_with_full_path ='/home/USERNAME/import.csv';
$post = array('file'=>'@'.$file_name_with_full_path);

$curl = curl_init();
curl_setopt($curl, CURLOPT_URL,$target_url);
curl_setopt($curl, CURLOPT_POST,1);
curl_setopt($curl, CURLOPT_POST, count($post)
curl_setopt($curl, CURLOPT_POSTFIELDS, $post);
curl_setopt($curl, CURLOPT_RETURNTRANSFER,true);
curl_setopt($curl, CURLOPT_VERBOSE,true);
$result = curl_exec($curl)
if(!$result){
    die('Error: "' . curl_error($curl) . '" - Code: ' . curl_errno($curl));
}
curl_close($curl);
var_dump($result);
?>
adkstar
  • 178
  • 1
  • 10
0

Use this lib https://github.com/php-curl-class/php-curl-class and then

$curl = new Curl();
$curl->post('https://www.example.com/login/', array(
    'username' => 'myusername',
    'password' => 'mypassword',
));
  • that definitely will not upload $file_name_with_full_path - but maybe this would (idk, i dont know that library): `$curl->post('https://www.example.com/login/', array( 'username' => 'myusername', 'password' => 'mypassword', 'file'=>new CURLFile($file_name_with_full_path) ));` – hanshenrik Oct 22 '17 at 09:56
  • Hi, This library is one of best curl lib for php. Please add library with instruction in this url [link]https://github.com/php-curl-class/php-curl-class/blob/master/README.md[/link] this. and then You can use some examle of this like file uploader. file uploader example: [link]https://github.com/php-curl-class/php-curl-class/blob/master/examples/multi_curl_upload_file.php[/link] – Meysam GanjAli Oct 23 '17 at 14:37
  • I don't know that library, and although I might check it out, I have little interest in learning it. But the point is, your example code does _NOT_ do what OP wants to do, you should probably fix that (also I'm the author of [another curl_ wrapper](https://github.com/divinity76/hhb_.inc.php/blob/master/hhb_.inc.php#L477) that does pretty much the same, and it's working fine for me, thus my disinterest) – hanshenrik Oct 23 '17 at 17:35
  • Thanks a lot for sharing link to the library, it is so handy and easy to use – Christopher Kikoti Oct 26 '18 at 18:43
0

You need to read file data and then attach data on post fields.

Try this, this should work. If doesn't work, make sure fread() can read your file. Reading can be failed due to many reason.

$target_url = 'https://apiprovider.com/api/v0/imports?token=[KEY]'

$file_name_with_full_path ='/home/USERNAME/import.csv';
$fileHandler = fopen($file_name_with_full_path, 'r');
$fileData = fread($fileHandler, filesize($file_name_with_full_path));

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL, target_url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");

$headers = array('file'=>'@'.$file_name_with_full_path);

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_INFILE, $fileHandler);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($file_name_with_full_path));

curl_setopt($ch, CURLOPT_POSTFIELDS, $fileData);

$result = curl_exec($ch);

curl_close ($ch);
var_dump($result);
Shamim Hossain
  • 1,690
  • 12
  • 21
  • no, it shouldn't work, and if this works for you, you should upgrade your PHP installation, because your PHP version is EOL. this wont work in PHP 5.6+. use CURLFile instead. – hanshenrik Oct 22 '17 at 12:08
  • no it doesnt. here is the request his curl command is making: https://gist.github.com/anonymous/b7e7057d995c0f310a84e81d71c9368b - and here is the request your php code is making (after fixing the typo on line 9 which makes your code connect to NULL-127.0.0.1 by mistake, you are missing a dollar sign): https://gist.github.com/anonymous/85f82e2787d9dd18b0ec44bb159f9a86 - those 2 requests are not even remotely similar. – hanshenrik Oct 22 '17 at 15:45
  • - but your code is failing in a different way than i initially thought when first reading through it. – hanshenrik Oct 22 '17 at 15:47
0

This worked for me. You can try it

  $authHeader = array('Accept: application/form-data');

  $post_fields =  "client_id=" . $client_id . "&client_secret=" . $client_secret;

  send_curl_request("POST", $authHeader, $url, $post_fields);

function send_curl_request($method, $headers, $url, $post_fields){
  $ch = curl_init();
  curl_setopt($ch, CURLOPT_URL,$url);
  if(count($headers) > 0){
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    //echo '<br> HEADER ADDED<br><br>';
  }
  curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $method);
  if($method == "POST"){
    curl_setopt($ch, CURLOPT_POST, 1);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $post_fields);
    //echo '<br> POST FIELDS ADDED<br><br>';
  } 
  curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
  curl_setopt($ch, CURLOPT_VERBOSE,true);
  $result = curl_exec($ch);
curl_close($ch);
return $result;
}
Junior
  • 1,007
  • 4
  • 16
  • 26