Curl POST文件上传失败排查:与Postman请求对比找问题
问题分析:PHP Curl 文件上传与 Postman 请求的差异及修复
首先来看你提供的Postman原始请求:
POST /upload.php HTTP/1.1 Host: 12.99.22.12 Cache-Control: no-cache Postman-Token: 79b6cf45-9180-70e1-2136-8af2f8f67271 Content-Type: multipart/form-data; boundary=----WebKitFormBoundary7MA4YWxkTrZu0gW ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="dosya"; filename="deneme--1.csv" Content-Type: application/vnd.ms-excel ------WebKitFormBoundary7MA4YWxkTrZu0gW Content-Disposition: form-data; name="yukle" Yükle ------WebKitFormBoundary7MA4YWxkTrZu0gW--
再对比你的PHP Curl代码:
$postfields = array("dosya" => "@$path","yukle"=>"Yükle","filename"=>"deneme--1.csv"); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL,$url); curl_setopt($ch, CURLOPT_POST,1); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: multipart/form-data')); curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields); //curl_setopt($ch, CURLOPT_HEADER , 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); $sonuc=curl_exec($ch); curl_close($ch);
核心差异与代码错误点
- 文件上传语法过时:你用的
@$path是PHP 5.5之前的旧版Curl文件上传写法,在PHP 5.5及以上版本已经被废弃,现在会被当作普通字符串传递,而非文件内容,这是上传失败的核心原因。 - 冗余的
filename字段:Postman请求里并没有单独的filename表单字段,你额外添加的这个字段会让发送的表单结构和Postman不一致,服务器可能无法正确解析。 - 手动设置
Content-Type错误:当你传递数组给CURLOPT_POSTFIELDS时,Curl会自动生成带正确boundary的multipart/form-data头部。但你手动设置的头部没有指定boundary,会导致服务器无法正确识别表单分隔符。
修正后的PHP Curl代码
根据Postman的请求结构,正确的代码应该如下:
// 先确保文件路径有效 $file_path = realpath($path); if (!file_exists($file_path) || !is_readable($file_path)) { die("文件不存在或无读取权限: " . $file_path); } // 使用PHP 5.5+支持的CURLFile类处理文件上传 $postfields = array( "dosya" => new CURLFile($file_path, "application/vnd.ms-excel", "deneme--1.csv"), "yukle" => "Yükle" ); $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, true); // 不要手动设置Content-Type,让Curl自动生成正确的头部(含boundary) curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1); curl_setopt($ch, CURLOPT_POSTFIELDS, $postfields); // 调试时可以开启查看请求头部 // curl_setopt($ch, CURLOPT_HEADER , 1); curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); // 添加超时设置避免无限等待 curl_setopt($ch, CURLOPT_TIMEOUT, 30); // 捕获返回内容而非直接输出 curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); $sonuc = curl_exec($ch); // 捕获Curl错误信息便于调试 if (curl_errno($ch)) { echo "Curl错误: " . curl_error($ch); } curl_close($ch); echo $sonuc;
额外注意事项
- 如果你仍在使用PHP 5.5以下的过时版本(不推荐),可以添加
curl_setopt($ch, CURLOPT_SAFE_UPLOAD, false);来兼容旧的@语法,但强烈建议升级PHP版本。 - 始终确保文件路径正确且有可读权限,否则Curl无法读取文件内容。
内容的提问来源于stack exchange,提问作者Zibian Domichi
相关产品推荐
相关产品推荐

