PHP5.6之后curl上传图片

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/austindev/article/details/54844724

PHP5.6 之后curl上传图片

问题描述

在开发微信公众号的过程中,需要上传临时资源图片,根据微信开发文档,采用curl进行后台的表单提交:

微信官方文档接口调用请求说明
http请求方式: POST/FORM
http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE
调用示例(使用curl命令,用FORM表单方式上传一个多媒体文件):
curl -F media=@test.jpg "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=ACCESS_TOKEN&type=TYPE"

根据上述文档,curl 上传图片的代码片段如下,这段代码在PHP5.5上正常运行:

$url = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token={$access_token}&type={$type}";
$data = array('media' => '@' . $img);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$info = curl_exec($ch);
curl_close($ch);
return $info;

最近升级到PHP7之后,出现上传图片失败:

{"errcode":41005,"errmsg":"media data missing hint: [lFlbea0043e621]"}

问题根源-@前缀使用

查看PHP官方手册,关于curl post 文件的传输CURLOPT_POSTFIELDS:

全部数据使用HTTP协议中的 "POST" 操作来发送。 要发送文件,在文件名前面加上@前缀并使用完整路径。 

文件类型可在文件名后以 ';type=mimetype' 的格式指定。 这个参数可以是 urlencoded 后的字符串,类似'para1=val1&para2=val2&...',也可以使用一个以字段名为键值,字段数据为值的数组。

 如果value是一个数组,Content-Type头将会被设置成multipart/form-data。 

从 PHP 5.2.0 开始,使用 @ 前缀传递文件时,value 必须是个数组。 从 PHP 5.5.0 开始, @ 前缀已被废弃,文件可通过 CURLFile 发送。 

设置 CURLOPT_SAFE_UPLOAD 为 TRUE 可禁用 @ 前缀发送文件,以增加安全性。

再查看CURLOPT_SAFE_UPLOAD相关说明:

PHP 5.5.0 中添加,默认值 FALSE。 PHP 5.6.0 改默认值为 TRUE

所以很清楚可以看到,我们的问题是上级到PHP7之后,默认的CURLOPT_SAFE_UPLOAD为TRUE,禁止@ 前缀发送文件;而且解决办法有两个:

  1. 设置CURLOPT_SAFE_UPLOAD为false;
  2. 采用CURLFile 安全上传文件;

采用CURLFile 安全上传文件

$url = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token={$access_token}&type={$type}";
//构建CURLFile文件
$cfile = new CURLFile("$img",'image/jpg');
$imgdata = array('media' => $cfile);

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_AUTOREFERER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $imgdata );
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$info = curl_exec($ch);
curl_close($ch);
return $info;

猜你喜欢

转载自blog.csdn.net/austindev/article/details/54844724