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

PHP FTP下载文件始终为0字节问题求助

问题分析与修复方案

你的代码存在两个核心问题,直接导致下载的文件始终为0字节:

  1. Content-Length头设置错误
    你用了filesize($size)来设置内容长度,但$size已经是ftp_size获取到的远程文件大小,filesize()是读取本地文件大小的函数,传入数字会返回false,导致浏览器无法识别正确的文件大小。

  2. readfile访问FTP时缺少身份验证
    你单独通过ftp_connect/ftp_login建立了连接,但readfile("ftp://...")是独立的请求,没有携带登录凭据,无法读取远程文件内容,所以输出为空。


修正后的代码

<?php
// 建立FTP连接并检查是否成功
$conn_id = ftp_connect("myftpserver.org");
if (!$conn_id) {
    die("无法连接到FTP服务器");
}

// 登录FTP并验证结果
$login_result = ftp_login($conn_id, "uname", "pword");
if (!$login_result) {
    ftp_close($conn_id);
    die("FTP登录失败");
}

$remote_file = $_REQUEST['downloadDir'] . "/" . $_REQUEST['file'];
// 获取远程文件大小
$size = ftp_size($conn_id, $remote_file);
if ($size == -1) {
    ftp_close($conn_id);
    die("无法获取远程文件大小");
}

// 设置响应头
header('Pragma: public');
header('Expires: 0');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
header('Cache-Control: private', false);
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . basename($_REQUEST['file']) . '";');
header('Content-Transfer-Encoding: binary');
header('Content-Length: ' . $size); // 直接使用ftp_size获取的结果

// 开启被动模式(多数FTP服务器要求)
ftp_pasv($conn_id, true);

// 输出远程文件内容
$output_handle = fopen('php://output', 'w');
if (ftp_fget($conn_id, $output_handle, $remote_file, FTP_BINARY)) {
    fclose($output_handle);
} else {
    die("读取远程文件失败");
}

// 关闭FTP连接
ftp_close($conn_id);
exit;
?>

额外提醒

  • 不要直接使用$_REQUEST,建议根据请求方式用$_GET或$_POST,同时要对downloadDir和file参数做安全校验,过滤../这类路径遍历字符,防止恶意访问。
  • 确认你的FTP服务器支持被动模式,大部分托管环境下被动模式是必须启用的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 19:44:55