You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP Curl请求附加CurlFile失效 求问题排查指引

PHP 5.6 cURL POST请求(带Token和图片)失败,HTTP状态码为0的排查与解决

问题描述

我尝试用PHP 5.6通过cURL向后端发起POST请求,需要附加Token和一张/多张图片文件。我用CurlFile创建了文件对象,也确认对象创建成功,但服务器始终接收不到请求,返回的cURL信息里http_code为0。

我的代码

$file_name_with_full_path = $_FILES["file-0"]["tmp_name"]; // 已验证正常
$target_url = $app_engine_url."images/upload";
$accessToken = $_SESSION['token'];
$imageName = basename($_FILES["file-0"]["name"]);
$filesize = $_FILES['file-0']['size'];

$postfields = array(
    "file" => makeCurlFile($file_name_with_full_path), 
    "filename" => $imageName,
    "access_token"=>$accessToken
);

$headers = array("Content-Type:multipart/form-data");
$ch = curl_init();
$options = array(
    CURLOPT_URL => $target_url,
    CURLOPT_HEADER => true,
    CURLOPT_POST => 1,
    CURLOPT_SAFE_UPLOAD => true,
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_INFILESIZE => $filesize,
    CURLOPT_POSTFIELDS => $postfields,
    CURLOPT_RETURNTRANSFER => true
);

curl_setopt_array($ch, $options);
$resp = curl_exec($ch);
echo $resp;

if(!curl_errno($ch)) {
    $info = curl_getinfo($ch);
    if ($info['http_code'] == 200)
        $errmsg = "File uploaded successfully";
} else {
    $errmsg = curl_error($ch);
}

print_r(curl_getinfo($ch));
curl_close($ch);
echo stripslashes($errmsg);
return null;
}

function makeCurlFile($file){
    $info = getimagesize($file);
    $mime = $info['mime'];
    $name = basename($_FILES["file-0"]["name"]);
    $output = new \CURLFile($file, $mime, $name);
    return $output;
    // 文件对象已验证创建成功
}

cURL响应结果

Array
(
 [url] => someurl.com // URL已确认正确
 [content_type] =>
 [http_code] => 0
 [header_size] => 0
 [request_size] => 0
 [filetime] => -1
 [ssl_verify_result] => 0
 [redirect_count] => 0
 [total_time] => 0.031
 [namelookup_time] => 0.015
 [connect_time] => 0.031
 [pretransfer_time] => 0
 [size_upload] => 0
 [size_download] => 0
 [speed_download] => 0
 [speed_upload] => 0
 [download_content_length] => -1
 [upload_content_length] => -1
 [starttransfer_time] => 0
 [redirect_time] => 0
 [redirect_url] =>
 [primary_ip] => 172.217.212.153
 [certinfo] => Array
 (
 )
 [primary_port] => 443
 [local_ip] => 10.128.0.3
 [local_port] => 49858
)

问题分析与解决方案

从http_code = 0和size_upload = 0可以看出,请求根本没有成功发送到服务器,大概率是cURL的配置有误导致连接或请求构建失败。以下是几个关键问题点和修复方案:

1. 移除手动设置的multipart/form-data请求头

当你使用CURLFile结合CURLOPT_POSTFIELDS时,cURL会自动生成正确的multipart/form-data请求头(包括边界标识)。手动设置这个头会导致边界不匹配,服务器无法解析请求,甚至直接中断连接。

修复: 删除$headers数组的定义和CURLOPT_HTTPHEADER的设置,或者清空这个数组。

2. 移除CURLOPT_INFILESIZE选项

这个选项是用于手动指定上传文件的大小,但当你通过CURLOPT_POSTFIELDS传递CURLFile对象时,cURL会自动获取文件大小并处理,手动设置反而会导致请求异常。

修复: 从$options数组中删除CURLOPT_INFILESIZE => $filesize这一行。

3. 添加HTTPS证书验证相关配置(针对443端口)

你的请求目标是HTTPS(端口443),PHP 5.6默认开启了SSL证书验证,如果服务器的SSL证书无法被本地CA库信任,会导致连接失败。可以根据情况调整:

  • 如果是生产环境,确保服务器证书有效,并配置正确的CA证书路径;
  • 如果是测试环境,可以临时关闭验证(不建议生产使用):
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => 0

4. 优化makeCurlFile函数(可选)

函数里直接引用$_FILES["file-0"]["name"]不够灵活,建议把文件名作为参数传入,避免依赖全局变量:

function makeCurlFile($file, $fileName){
    $info = getimagesize($file);
    $mime = $info['mime'];
    $output = new \CURLFile($file, $mime, $fileName);
    return $output;
}

调用时改为:

"file" => makeCurlFile($file_name_with_full_path, $imageName)

修改后的完整代码

$file_name_with_full_path = $_FILES["file-0"]["tmp_name"];
$target_url = $app_engine_url."images/upload";
$accessToken = $_SESSION['token'];
$imageName = basename($_FILES["file-0"]["name"]);

$postfields = array(
    "file" => makeCurlFile($file_name_with_full_path, $imageName), 
    "filename" => $imageName,
    "access_token"=>$accessToken
);

$ch = curl_init();
$options = array(
    CURLOPT_URL => $target_url,
    CURLOPT_HEADER => true,
    CURLOPT_POST => 1,
    CURLOPT_SAFE_UPLOAD => true,
    CURLOPT_POSTFIELDS => $postfields,
    CURLOPT_RETURNTRANSFER => true,
    // 测试环境临时关闭SSL验证,生产环境请移除并配置CA证书
    CURLOPT_SSL_VERIFYPEER => false,
    CURLOPT_SSL_VERIFYHOST => 0
);

curl_setopt_array($ch, $options);
$resp = curl_exec($ch);
echo $resp;

$errmsg = "";
if(!curl_errno($ch)) {
    $info = curl_getinfo($ch);
    if ($info['http_code'] == 200) {
        $errmsg = "File uploaded successfully";
    } else {
        $errmsg = "HTTP status code: " . $info['http_code'];
    }
} else {
    $errmsg = curl_error($ch);
}

print_r(curl_getinfo($ch));
curl_close($ch);
echo stripslashes($errmsg);
return null;
}

function makeCurlFile($file, $fileName){
    $info = getimagesize($file);
    $mime = $info['mime'];
    $output = new \CURLFile($file, $mime, $fileName);
    return $output;
}

内容的提问来源于stack exchange,提问作者Elinoter99

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.13 09:12:39