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

PHP CURL上传至Google Cloud Storage遇问题:文件上传后为0字节

解决PHP CURL上传文件为空(0字节)的问题

问题根源分析

你当前用的Postman生成代码里,CURLOPT_POSTFIELDS是硬编码的空文件内容——只有表单边界和文件元信息,完全没有实际的文件二进制数据,所以上传后自然是0字节的空文件。要解决这个问题,我们需要动态读取本地文件并正确构造multipart/form-data请求。

推荐方案:使用PHP CURLFile类(PHP 5.5+)

这是PHP官方推荐的文件上传处理方式,能自动处理边界、文件内容和头信息,避免手动构造出错:

<?php
// 替换成你实际要上传的本地文件路径
$filePath = '/path/to/your/current-logo.png';
// 先检查文件是否存在且可读
if (!file_exists($filePath) || !is_readable($filePath)) {
    die("错误:目标文件不存在或无法读取");
}

$curl = curl_init();

// 用CURLFile构造文件上传参数,自动处理MIME类型和文件名
$postFields = array(
    'filename' => new CURLFile($filePath, mime_content_type($filePath), 'current-logo.png')
);

curl_setopt_array($curl, array(
    CURLOPT_URL => "http://acquired-backup-198200.appspot.com/upload?uname=arun@gmail.com",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => $postFields,
    // 不需要手动设置Content-Type,CURL会自动生成正确的multipart/form-data头
    CURLOPT_HTTPHEADER => array(
        "Cache-Control: no-cache"
        // 移除Postman-Token,这只是测试用头,线上不需要
    ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    echo "cURL错误 #: " . $err;
} else {
    echo $response;
}
?>

兼容老版本PHP(<5.5)的方案

如果你的PHP版本低于5.5,可以手动构造multipart/form-data请求体,但要注意正确读取文件内容:

<?php
$filePath = '/path/to/your/current-logo.png';
if (!file_exists($filePath) || !is_readable($filePath)) {
    die("错误:目标文件不存在或无法读取");
}

// 生成随机边界字符串,避免和文件内容冲突
$boundary = '----WebKitFormBoundary' . uniqid(mt_rand(), true);
$fileContent = file_get_contents($filePath);
$mimeType = mime_content_type($filePath);

// 手动构造POST请求体,包含实际文件内容
$postBody = "--$boundary\r\n"
           . "Content-Disposition: form-data; name=\"filename\"; filename=\"current-logo.png\"\r\n"
           . "Content-Type: $mimeType\r\n\r\n"
           . $fileContent . "\r\n"
           . "--$boundary--\r\n";

$curl = curl_init();

curl_setopt_array($curl, array(
    CURLOPT_URL => "http://acquired-backup-198200.appspot.com/upload?uname=arun@gmail.com",
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_ENCODING => "",
    CURLOPT_MAXREDIRS => 10,
    CURLOPT_TIMEOUT => 30,
    CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
    CURLOPT_CUSTOMREQUEST => "POST",
    CURLOPT_POSTFIELDS => $postBody,
    CURLOPT_HTTPHEADER => array(
        "Cache-Control: no-cache",
        "Content-Type: multipart/form-data; boundary=$boundary"
    ),
));

$response = curl_exec($curl);
$err = curl_error($curl);

curl_close($curl);

if ($err) {
    echo "cURL错误 #: " . $err;
} else {
    echo $response;
}
?>

关键注意事项

  • 如果是前端用户上传的文件,要先通过$_FILES获取服务器临时文件路径(比如$_FILES['user_upload']['tmp_name']),再传入代码中使用。
  • 确保服务器对目标文件路径有读取权限,否则会出现文件无法读取的错误。
  • 优先使用CURLFile方案,代码更简洁且不易出错,同时支持大文件上传(避免file_get_contents读取大文件占用过多内存)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.27 09:55:00