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

PHP使用Curl从GitHub仓库下载Zip文件生成空文件的问题求助

解决PHP Curl下载GitHub仓库Zip文件为空的问题

问题背景

根据GitHub文档,使用以下命令行Curl可成功下载GitHub仓库的Zip文件:

curl -L -H "Accept: application/vnd.github+json" -H "Authorization: Bearer <MY TOKEN>" -H "X-GitHub-Api-Version: 2022-11-28" https://api.github.com/repos/<MY_GIT_NAME>/<REPO>/zipball/master --output "download.zip"

将该逻辑转为PHP代码后,执行返回true但生成的Zip文件为空:

$f = fopen(__DIR__.'/download.zip', 'w+');

$ch = curl_init();
$url = "https://api.github.com/repos/$user/$repo/zipball/master";

$opt = [
    CURLOPT_URL => $url,
    CURLOPT_CUSTOMREQUEST => 'GET',
    CURLOPT_RETURNTRANSFER => 1,
    CURLOPT_FILE => $f,
];
curl_setopt_array($ch, $opt);

$headers = array(
    "Accept: application/vnd.github+json",
    "Authorization: Bearer $token",
    "X-Github-Api-Version: 2022-11-28",
);

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}
curl_close($ch);

排查过程

  • 代码执行耗时极短,与命令行下载的耗时差异明显,通过curl_getinfo排查发现HTTP状态码为403。
  • 添加User-Agent请求头后,状态码变为302,但Zip文件仍为空。

解决方法

问题出在以下几个Curl配置缺失或冲突,修正后的代码如下:

$f = fopen(__DIR__.'/download.zip', 'wb');

$ch = curl_init();
$url = "https://api.github.com/repos/$user/$repo/zipball/master";

$opt = [
    CURLOPT_URL => $url,
    CURLOPT_FOLLOWLOCATION => true, // 跟随重定向,对应命令行的-L参数
    CURLOPT_FILE => $f,
    CURLOPT_USERAGENT => 'PHP-Curl', // 明确设置合法的User-Agent
    CURLOPT_SSL_VERIFYPEER => true,
];
curl_setopt_array($ch, $opt);

$headers = array(
    "Accept: application/vnd.github+json",
    "Authorization: Bearer $token",
    "X-GitHub-Api-Version: 2022-11-28",
);

curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);

$response = curl_exec($ch);
if (curl_errno($ch)) {
    echo 'Error:' . curl_error($ch);
}

// 可选:检查最终HTTP状态码
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode !== 200) {
    echo "HTTP请求失败,状态码: $httpCode";
}

curl_close($ch);
fclose($f); // 必须关闭文件句柄,确保内容写入磁盘

关键修正点说明

  • 添加CURLOPT_FOLLOWLOCATION => true:GitHub API接口会返回302重定向到实际的Zip文件存储地址,必须开启跟随重定向才能获取到文件内容,对应命令行的-L参数。
  • 移除CURLOPT_RETURNTRANSFER => 1:该选项会将请求结果返回给变量,与CURLOPT_FILE(将结果写入文件)冲突,同时开启会导致文件无法写入内容。
  • 明确设置User-Agent:GitHub API要求请求必须携带合法的User-Agent,使用固定值比依赖$_SERVER['HTTP_USER_AGENT']更可靠,避免环境中该值为空导致的请求被拦截。
  • 使用wb模式打开文件:二进制写入模式可避免不同操作系统下的换行符转换问题,保证Zip文件的完整性。
  • 关闭文件句柄:执行完Curl请求后,必须关闭fopen打开的文件句柄,确保所有内容都写入磁盘。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.23 15:05:02