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。
但是坑的一點在於:@
語法在5.5就已經被打了deprecated,在5.6中就直接被刪除了(會產生 ErorException: The usage of the @filename
API for file uploading is deprecated. Please use the CURLFile class instead)。
對於PHP 5.6+而言,手動設置CURL_SAFE_UPLOAD
為false是毫無意義的。根本不是字面意義理解的“設置成false,就能開啟舊的unsafe的方式”——舊的方式已經作為廢棄語法徹底不存在了。PHP 5.6+ == CURLFile only,不要有任何的幻想。
我的部署環境是5.4(僅@
語法),但開發環境是5.6(僅CURLFile)。都沒有壓在5.5這個兩者都支持過渡版本上,結果就是必須寫出帶有環境判斷的兩套代碼。
環境判斷的代碼:
if (version_compare(phpversion(), '5.4.0') >= 0) 可以使用 但不推薦,畢竟帶有魔法數字
最后感謝, 這篇博客