需要注意的是,ftp_pasv 必须在 ftp_login 后调用(而不是在 ftp_connect 后)。这对于许多人来说可能显而易见,但我花了三个小时才弄清楚...
(PHP 4, PHP 5, PHP 7, PHP 8)
ftp_pasv — 打开或关闭被动模式
ftp_pasv() 打开或关闭被动模式。在被动模式下,数据连接由客户端而不是服务器发起。如果客户端位于防火墙后面,可能需要使用它。
请注意,ftp_pasv() 只能在成功登录后调用,否则将失败。
版本 | 说明 |
---|---|
8.1.0 | 现在,ftp 参数需要一个 FTP\Connection 实例;以前需要一个 资源。 |
示例 #1 ftp_pasv() 示例
<?php
$file = 'somefile.txt';
$remote_file = 'readme.txt';
// 设置基本连接
$ftp = ftp_connect($ftp_server);
// 使用用户名和密码登录
$login_result = ftp_login($ftp, $ftp_user_name, $ftp_user_pass);
// 打开被动模式
ftp_pasv($ftp, true);
// 上传文件
if (ftp_put($ftp, $remote_file, $file, FTP_ASCII)) {
echo "成功上传 $file\n";
} else {
echo "上传 $file 时出现问题\n";
}
// 关闭连接
ftp_close($ftp);
?>
需要注意的是,ftp_pasv 必须在 ftp_login 后调用(而不是在 ftp_connect 后)。这对于许多人来说可能显而易见,但我花了三个小时才弄清楚...
对于某些 FTP 服务器,被动命令和其他命令的顺序似乎比其他 FTP 服务器更重要。抱歉,我不知道具体的供应商或版本。
<?php
ftp_pasv($handle, true);
echo "系统类型: ".ftp_systype($handle).PHP_EOL;
ftp_fput($handle, 'example.txt', $stream, FTP_BINARY);
?>
> PHP 警告:ftp_fput():STOR 顺序错误。
<?php
echo "系统类型: ".ftp_systype($handle).PHP_EOL;
ftp_pasv($handle, true);
ftp_fput($handle, 'example.txt', $stream, FTP_BINARY);
?>
> 没有问题
如果您在 Windows 上以被动模式运行 filezilla,并尝试使用 PHP 连接,您可能会遇到一个错误,提示“425 无法打开数据连接以传输...”
此错误不表示被动模式问题,但可以通过以下方法解决
<?php
ftp_pasv($conn, true);
?>
如果您在选择 ftp_pasv() 后仍然遇到问题,您应该在传输 x 个文件和/或 y GB 数据后,通过 ftp_close() / ftp_connect() 刷新连接。
它解决了几个(随机发生的)问题,例如
ftp_get():正在打开二进制模式数据连接
ftp_get():正在进入被动模式
提示:fopen() 创建了一个文件,因此如果出现错误,请不要忘记删除它;)
我发现一个地方需要被动模式才能正常工作,但最初的错误以一种奇怪的方式显现出来
PHP 警告:ftp_put():TYPE 现在为 ASCII in <file.php> on line <#>
或者
PHP 警告:ftp_put():TYPE 现在为 8 位二进制 in <file.php> on line <#>
另一个症状是它需要很长时间,可能是超时设置为 90 秒。连接时没有发生错误,只发生在尝试 ftp_put() 时。
一旦我打开了 ftp_pasv(),它就能够工作,无论是在主动模式工作的地方,还是在主动模式无法工作的地方。
直接来自 bsd FTP 手册页
PASV 命令请求远程服务器为数据连接打开一个端口并返回该端口的地址。远程服务器监听该端口,客户端连接到它。
使用更传统的 PORT 命令时,客户端监听一个端口并将该地址发送到远程服务器,远程服务器连接回它。当通过控制流量方向的网关路由器或主机使用 ftp 时,被动模式很有用。(请注意,尽管 RFC 1123 要求 ftp 服务器支持 PASV 命令,但有些服务器不支持。)