this is what you want: remove CURLOPT_POSTFIELDS altogether, and replace CURLOPT_CUSTOMREQUEST=>'PUT'
with CURLOPT_UPLOAD=>1
and replace 'r'
with 'rb'
, and use CURLOPT_INFILE (you’re supposed to use INFILE instead of POSTFIELDS),
$fp = fopen($_FILES['file']['tmp_name'], "rb");
curl_setopt_array($ch,array(
CURLOPT_UPLOAD=>1,
CURLOPT_INFILE=>$fp,
CURLOPT_INFILESIZE=>$_FILES['file']['size']
));
This works when I had $file = fopen($temp_name, ‘r’);
never use the r
mode, always use the rb
mode (short for “binary mode”), weird things happen if you ever use the r
mode on Windows, r
is short for “text mode” – if you actually want text mode, use rt
(and unless you really know what you’re doing, you don’t want the text mode, ever, unfortunate that it’s the default mode),
but the file uploaded was a weird file. (…) This is what the file looks like when the person at the other end of this API tries to open it.
well you gave CURLOPT_POSTFIELDS a resource. CURLOPT_POSTFIELDS accepts 2 kinds of arguments, #1: an array (for multipart/form-data
requests), #2: a string (for when you want to specify the raw post body data), it does not accept resources.
if the php curl api was well designed, you would get an InvalidArgumentException, or a TypeError, when giving CURLOPT_POSTFIELDS a resource. but it’s not well designed. instead, what happened is that curl_setopt implicitly casted your resource to a string, hence resource id #X
, it’s the same as doing
curl_setopt($request, CURLOPT_POSTFIELDS, (string) fopen(...));
solved Uploading a file to Google Signed URL with PHP cURL