1

I'm trying to get data posted using cURL in my endpoint, which is built on Laravel. In my API controller, where I receive data, I am able to receive all the data except my media file. I check for presence of the file using $request->hasFile('file') but it returns false. I also try to get the file using $request->file('file') but it returns null.

When I use $request->get('file'), I get the following response.

Laravel : 5.5

PHP 7.2.1

file":{"name":"/Users/name/File/path/public/media/aaaah.wav","mime":null,"postname":null}

Below, I am using $headers[] = "Content-Type: application/json"; to convert the recipient from array to string. Can anyone help me understand why the file posted by cURL is not being received in my Laravel method when I use $request->hasFile('file') and $request->file('file')?

AppController

public function postCurlData()
{
   $endPoint = 'http://127.0.0.1:9000/api';          
   $apiKey = '****';
   $url = $endPoint . '?key=' . $apiKey;
   $dir = '/Users/name/File/path/app/public/media/test.wav'; // full directory of the file
   $curlFile = curl_file_create($dir);

    $data = [
       'recipient' => ['44909090', '44909090'],
       'content' => 'i love to code',
       'file' => $curlFile,          
     ];

    $ch = curl_init();
    $headers = array();
    $headers[] = "Content-Type: application/json";
    curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    $result = curl_exec($ch);
    $result = json_decode($result, TRUE);
    curl_close($ch);
}

My endpoint where I'm receiving data:

APIController

public function receiveCurlData()   
{   
    $apiKey = $request->get('key');
    if (($apiKey)) {
        return response()->json([
            'status' => 'success',
            'content' => $request->get('content'),
            'recipient' => $request->get('recipient'),
            'file' => $request->hasFile('file')                 
        ]);
    }
}

Response

{"status":"success","content":"I love to code","recipient":
["44909090","44909090"],"file":false}
CodeNewbie
  • 49
  • 3
  • 11
  • You'll have a much easier time working with Guzzle: http://docs.guzzlephp.org/en/stable/ – ceejayoz Jan 15 '19 at 14:50
  • @ceejayoz, why would you prefer Guzzle to Curl ? – CodeNewbie Jan 15 '19 at 14:53
  • Because it's designed specifically for this sort of thing, and will handle automatically most of the common screw-ups in making cURL calls. – ceejayoz Jan 15 '19 at 15:01
  • _“Can anyone help me understand why the file posted by cURL is not being received in my Laravel method”_ - this happens _because_ you messed with the Content-Type. PHP has no default mechanism to extract file upload data from JSON; you _need_ to send a `multipart/form-data` request. – misorude Jan 15 '19 at 15:13
  • @misorude, I am still not able to get the file even it is `multipart/form-data`. That is actually the first i tried :) – CodeNewbie Jan 15 '19 at 15:19
  • Try and take this as orientation: https://stackoverflow.com/a/15200804/10283047 – misorude Jan 15 '19 at 15:24
  • Did my answer help in any way? – Osakr Jan 16 '19 at 09:00
  • @Osakr, the error still exist with your answer but thanks – CodeNewbie Jan 22 '19 at 14:14

1 Answers1

1

If you're sending files then I recommend you to set the curl safe upload:

curl_setopt($ch, CURLOPT_SAFE_UPLOAD, true);

Then you might need to change the Content-Type of the header and set this:

"Content-Type: multipart/form-data"

Also I usually use this approach instead of curl_file_create

if ( class_exists('CurlFile') ) {
  $file = new CurlFile('path-to-the-file', 'application/octet-stream');
} else {
  $file = '@' . realpath('path-to-the-file');
}

Anyways I would say ( but not totally sure ) that the problem with your code is the Content-Type header which is set to JSON

Osakr
  • 1,027
  • 1
  • 13
  • 26