PHP FTP下载文件始终为0字节问题求助
问题分析与修复方案
你的代码存在两个核心问题,直接导致下载的文件始终为0字节:
Content-Length头设置错误
你用了filesize($size)来设置内容长度,但$size已经是ftp_size获取到的远程文件大小,filesize()是读取本地文件大小的函数,传入数字会返回false,导致浏览器无法识别正确的文件大小。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
相关产品推荐
相关产品推荐

