需要注意的是,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 BIT BINARY in <file.php> on line <#>
另一个症状是它花费了很长时间,也许是超时设置的90秒。连接时没有发生错误,只是在我尝试使用ftp_put()时才出现。
一旦我开启了ftp_pasv(),它就在主动模式有效的环境和主动模式无效的服务器上都工作了。
直接来自bsd FTP 手册页
PASV 命令请求远程服务器打开一个端口用于数据连接,并返回该端口的地址。远程服务器监听该端口,客户端连接到它。
当使用更传统的PORT命令时,客户端监听一个端口并将该地址发送到远程服务器,远程服务器连接回它。当通过控制流量方向的网关路由器或主机使用ftp时,被动模式非常有用。(请注意,尽管RFC 1123要求ftp服务器支持PASV命令,但有些服务器不支持。)