參考文檔: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,然后發送出去,能實現更好的兼容性,更小的請求數據包。