参考文档:https://www.cnblogs.com/Alight/p/4330236.html
$accessToken = $this->getAccessToken(); if (empty($accessToken)) { return ['msg' => 'token缺失']; } // 文件路径使用绝对路径 // 方式一、使用'@'符号加上文件的绝对路径来指引文件。适合PHP5.5之前的版本 // $data = ['media' => new CURLFile(ROOT_PATH . $filepath)]; // 方式二、从PHP5.5版本以后,引入了新的CURLFile 类来指向文件,参数传入的也是绝对路径 $data = ['media' => new CURLFile(ROOT_PATH . $filepath)]; $url = self::UPLOAD_IMG_URL . $accessToken; return $this->httpPost($url, $data);
问题延伸:上面的请求中,POST参数是传递的数组,那么PHP的CURLOPT\_POSTFIELDS参数使用数组和字符串的区别?
手册上解释:
全部数据使用HTTP协议中的"POST"操作来发送。要发送文件,在文件名前面加上@前缀并使用完整路径。这个参数可以通过urlencoded后的字符串类似'para1=val1¶2=val2&...'或使用一个以字段名为键值,字段数据为值的数组。如果value是一个数组,Content-Type头将会设置成multipart/form-data。
尝试发送到一个仅有<?php print_r($_SERVER);?>的网页上,可以看到使用数组发送POST数据时,收到的CONTENT_TYPE如下:
[CONTENT_TYPE] => multipart/form-data; boundary=—————————-f924413ea122
而使用http_build_query($post_data),收到的CONTENT_TYPE如下:
[CONTENT_TYPE] => application/x-www-form-urlencoded
- 可见,当CURLOPT_POSTFIELDS被设置为数组时,HTTP头会发送Content_type: application/x-www-form-urlencoded。这个是正常的网页<form>提交表单时,浏览器发送的头部。而multipart/form-data我们知道这是用于上传文件的表单。包括了boundary分界符,会多出很多字节。
手册上提到:
使用数组提供post数据时,CURL组件大概是为了兼容@filename这种上传文件的写法,默认把content_type设为了multipart/form-data。虽然对于大多数web服务器并没有影响,但是还是有少部分服务器不兼容。
- 得出的结论是,在没有需要上传文件的情况下,尽量对post提交的数据进行http_build_query,然后发送出去,能实现更好的兼容性,更小的请求数据包。