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
相关产品推荐
相关产品推荐

