【PHP】Php curl 上传文件

参考文档: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&para2=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,然后发送出去,能实现更好的兼容性,更小的请求数据包。
得意时做事,失意时读书
原文地址:https://www.cnblogs.com/lanse1993/p/14785724.html