文鏈接: http://www.maoyupeng.com/wechart-upload-image-errorcode-41005.html
PHP的cURL支持通過給CURL_POSTFIELDS
傳遞關聯數組(而不是字符串)來生成multipart/form-data
的POST請求。
傳統上,PHP的cURL支持通過在數組數據中,使用“@
+文件全路徑”的語法附加文件,供cURL讀取上傳。這與命令行直接調用cURL程序的語法是一致的:
curl_setopt(ch, CURLOPT_POSTFIELDS, array(
'file' => '@'.realpath('image.png'), )); equals $ curl -F "file=@/absolute/path/to/image.png" <url>
但PHP從5.5開始引入了新的CURLFile類用來指向文件。CURLFile類也可以詳細定義MIME類型、文件名等可能出現在multipart/form-data數據中的附加信息。PHP推薦使用CURLFile替代舊的@
語法:
curl_setopt(ch, CURLOPT_POSTFIELDS, [
'file' => new CURLFile(realpath('image.png')), ]);
PHP 5.5另外引入了CURL_SAFE_UPLOAD
選項,可以強制PHP的cURL模塊拒絕舊的@
語法,僅接受CURLFile式的文件。5.5的默認值為false,5.6的默認值為true。
微信公眾號多媒體上傳接口返回碼出現41005的原因就是不能識別文件.
歸根到底,可能開發者沒有太在乎php版本之間的更新和差異,所以導致在低版本的php環境開發的,然后部署到高版本的環境中.
需要注意的是php5.4 php5.5 php5.6三個版本都有所不同.下面我貼出一段上傳圖片代碼,供大家參考(能兼容三個版本):
- $filepath = dirname ( __FILE__ ) . "/a.jpg";
- if (class_exists ( '\CURLFile' )) {//關鍵是判斷curlfile,官網推薦php5.5或更高的版本使用curlfile來實例文件
- $filedata = array (
- 'fieldname' => new \CURLFile ( realpath ( $filepath ), 'image/jpeg' )
- );
- } else {
- $filedata = array (
- 'fieldname' => '@' . realpath ( $filepath )
- );
- }
- $url = "http://file.api.weixin.qq.com/cgi-bin/media/upload?access_token=" . $access_token . "&type=image";
- $result = Http::upload ( $url, $filedata );//調用upload函數
- if (isset ( $result )) {
- $data = json_decode ( $result );
- if (isset ( $data->media_id )) {
- $this->responseText ( $data->media_id );//這是我自己封裝的返回消息函數
- } else {
- $this->responseImg ( "not set media_id" );//這是我自己封裝的返回消息函數
- }
- } else {
- $this->responseText ( "no response" );//這是我自己封裝的返回消息函數
- }
- public static function upload($url, $filedata) {
- $curl = curl_init ();
- if (class_exists ( '/CURLFile' )) {//php5.5跟php5.6中的CURLOPT_SAFE_UPLOAD的默認值不同
- curl_setopt ( $curl, CURLOPT_SAFE_UPLOAD, true );
- } else {
- if (defined ( 'CURLOPT_SAFE_UPLOAD' )) {
- curl_setopt ( $curl, CURLOPT_SAFE_UPLOAD, false );
- }
- }
- curl_setopt ( $curl, CURLOPT_URL, $url );
- curl_setopt ( $curl, CURLOPT_SSL_VERIFYPEER, FALSE );
- curl_setopt ( $curl, CURLOPT_SSL_VERIFYHOST, FALSE );
- if (! empty ( $filedata )) {
- curl_setopt ( $curl, CURLOPT_POST, 1 );
- curl_setopt ( $curl, CURLOPT_POSTFIELDS, $filedata );
- }
- curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, 1 );
- $output = curl_exec ( $curl );
- curl_close ( $curl );
- return $output;
- }