PHP连接FTP无法列出目录文件,仅FileZilla主动模式可正常访问
问题核心原因
PHP内置的FTP扩展默认启用被动模式,你的环境下被动模式不可用,且默认配置和FTP服务器的要求不匹配,才会出现连接正常但列表操作失败、调用列表接口后连接被破坏的问题。
可直接落地的解决方法
方案1:调整原生FTP扩展配置
按以下要求修改代码即可:
- 登录后显式关闭被动模式,启用主动模式(该配置必须放在
ftp_login之后才生效) - 匹配FileZilla的操作逻辑,设置二进制传输模式、开启UTF8支持
- 列表接口直接传入绝对路径
/,避免相对路径识别异常
修改后的测试代码:
$connection = ftp_connect($host, 21); if (!$connection) die('FTP连接失败'); $loginRes = ftp_login($connection, $username, $password); if (!$loginRes) die('FTP登录失败'); // 核心配置:关闭被动模式,启用主动模式 ftp_pasv($connection, false); // 设置二进制传输模式,匹配服务器要求 ftp_set_option($connection, FTP_BINARY, true); // 开启UTF8支持,匹配FileZilla的请求逻辑 ftp_raw($connection, 'OPTS UTF8 ON'); var_dump(ftp_size($connection, 'tarbert.jpg')); var_dump(ftp_mlsd($connection, '/')); var_dump(ftp_rawlist($connection, '/')); var_dump(ftp_nlist($connection, '/')); ftp_close($connection);
方案2:改用curl扩展实现(兼容性更高)
从你提供的curl测试日志可知curl可以正常拉取列表,这种方式无需适配FTP扩展的各种细节,更稳定:
$ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "ftp://{$host}/"); curl_setopt($ch, CURLOPT_USERPWD, "{$username}:{$password}"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_FTPLISTONLY, 1); // 强制主动模式,不需要的话删掉这行即可 curl_setopt($ch, CURLOPT_FTPPORT, '-'); $listRaw = curl_exec($ch); curl_close($ch); $fileList = explode("\n", trim($listRaw)); var_dump($fileList);
异常现象解释
之前把ftp_size放到列表函数之后会返回false,是因为列表操作触发了超时的被动模式连接尝试,直接破坏了原有FTP连接的状态,导致后续所有操作都失效。
内容的提问来源于stack exchange,提问作者kinger198
相关产品推荐
相关产品推荐

