PHP5.6之後curl上傳圖片
阿新 • • 發佈:2019-01-02
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 [email protected].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]"}
問題根源[email protected]字首使用
檢視PHP官方手冊,關於curl post 檔案的傳輸CURLOPT_POSTFIELDS:
全部資料使用HTTP協議中的 "POST" 操作來發送。 要傳送檔案,在檔名前面加上@字首並使用完整路徑。
檔案型別可在檔名後以 ';type=mimetype' 的格式指定。 這個引數可以是 urlencoded 後的字串,類似'para1=val1¶2=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,禁止@ 字首傳送檔案;而且解決辦法有兩個:
- 設定CURLOPT_SAFE_UPLOAD為false;
- 採用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;