dongping5230
2018-03-23 14:19
浏览 590
已采纳

PHP cURL文件获取内容始终为空

I've created an endpoint in Paw (and/or Postman) for handling file uploads. It works great!

enter image description here

It's pretty simple. And in my application I can do something like:

echo file_get_contents('php://input');

And it will print out an encoded representation of the image/file (a cute kitten).

The problem is, I cannot seem to reproduce this behaviour using just cURL (Current application uses Guzzle).

When I try something like:

$target_url = 'http://my-document-handling-service.net:8000/documents';

$request = curl_init($target_url);

curl_setopt($request, CURLOPT_POST, true);
curl_setopt($request, CURLOPT_RETURNTRANSFER, true);
curl_setopt($request, CURLOPT_POSTREDIR, 3);

curl_setopt(
    $request,
    CURLOPT_POSTFIELDS,
    array(
      'file' => '/Users/xxxxxxx-xxxx/Documents/kitten-test-upload-image-1.jpg'
    ));

echo curl_exec($request);

curl_close($request);

The body (file_get_contents()) is always empty. I don't really understand cURL I've always just used Guzzle - but now I have to use cURL and I can't get the body.

What am I doing wrong?

  • 点赞
  • 写回答
  • 关注问题
  • 收藏
  • 邀请回答

2条回答 默认 最新

  • dongzhao2725 2018-03-23 15:04
    已采纳

    (too long for a comment, the existing answer is very close to being correct, albeit bugged and won't work, but doesn't say why your origianl code failed) - when you give CURLOPT_POSTFIELDS an array, it encodes the input in multipart/form-data-format, and PHP parses multipart/form-data into $_POST (and for file uploads, $_FILES), and empties php://input in the process (it does this for any encoding it has built-in support for, and as of writing, there are 2, application/x-www-form-urlencoded, andmultipart/form-data`), and your code

    curl_setopt(
        $request,
        CURLOPT_POSTFIELDS,
        array(
          'file' => '/Users/xxxxxxx-xxxx/Documents/kitten-test-upload-image-1.jpg'
        ));
    

    sends the variable file with the value '/Users/xxxxxxx-xxxx/Documents/kitten-test-upload-image-1.jpg' to the server in the multipart/form-data format, thus your value is actually in $_POST['file'], but if you want to send the raw image directly, no encoding, so you can use php://input on the target server, use CURLOPT_INFILE or CURLOPT_POSTFIELDS, for example

    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    curl_setopt($ch, CURLOPT_INFILE,($fp=fopen('abc.txt','rb')));
    curl_setopt($ch, CURLOPT_INFILESIZE,123);
    (...)
    curl_exec($ch);
    fclose($fp);
    

    or

    curl_setopt($ch,CURLOPT_POSTFIELDS,file_get_contents("abc.txt"));
    curl_setopt($ch,CURLOPT_HTTPHEADER,array('Content-Type: application/octet-stream'));
    curl_exec($ch);
    

    (note that the second method will use more ram, it will put the entire file in memory prior to uploading, while the first method will send the data in chunks, making it possible to upload any size files without running out of ram, unlike the second method)

    点赞 打赏 评论
  • dtpw54085 2018-03-23 14:39

    Normally CURL will send the Postfields encoded with application/x-www-form-urlencoded or multipart/form-data. (Details).

    What you need is a RAW Encoding in the POST Data. I haven't test it yet. But it would be something like:

    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
    $res=fopen("abc.txt","rb"));   //CURLOPT_INFILE needs a stream resource
    curl_setopt($ch, CURLOPT_INFILE, $res);
    curl_setopt($ch, CURLOPT_INFILESIZE,123);
    ...
    curl_exec($ch);
    ...
    fclose($res);
    
    点赞 打赏 评论

相关推荐 更多相似问题