ftp_ssl_connect() 函数用于建立安全的 SSL-FTP 连接(也称为 FTPS 或 FTP over SSL)。
与普通的 ftp_connect() 不同,该函数通过 SSL/TLS 加密整个 FTP 会话,提供数据传输的安全性。
ftp_ssl_connect() 被标记为已弃用,建议使用更现代的 SFTP 协议(通过 SSH2 扩展)或 FTPES(FTP over explicit SSL/TLS)。
ftp_ssl_connect ( string $hostname [, int $port = 21 [, int $timeout = 90 ]] ) : resource|false
| 参数 | 类型 | 描述 |
|---|---|---|
$hostname |
string | 必需的。FTP 服务器的主机名或 IP 地址。 |
$port |
int | 可选的。FTP 服务器的端口号。默认是 21(标准 FTP 端口)。对于 FTPS,有时使用端口 990。 |
$timeout |
int | 可选的。连接超时时间(秒)。默认是 90 秒。 |
| 返回值 | 描述 |
|---|---|
| resource | 成功时返回一个 SSL-FTP 连接资源,用于后续的 FTP 函数调用。 |
false |
连接失败时返回 false。失败原因可能包括:
|
使用 ftp_ssl_connect() 前,确保满足以下要求:
--enable-ftp)--with-openssl)<?php
// 检查 FTP 扩展是否加载
if (!extension_loaded('ftp')) {
echo 'FTP 扩展未加载。请启用 FTP 扩展。';
}
// 检查 OpenSSL 扩展是否加载
if (!extension_loaded('openssl')) {
echo 'OpenSSL 扩展未加载。请启用 OpenSSL 扩展。';
}
// 检查函数是否存在
if (!function_exists('ftp_ssl_connect')) {
echo 'ftp_ssl_connect() 函数不可用。';
} else {
echo '支持 ftp_ssl_connect() 函数。';
}
// 或者使用 phpinfo() 查看详细信息
// phpinfo();
?>
以下示例展示了如何建立安全的 SSL-FTP 连接。
<?php
// 建立 SSL-FTP 连接
$ftp_server = "ftp.example.com";
$ftp_user = "username";
$ftp_pass = "password";
// 尝试建立 SSL 连接
$conn = ftp_ssl_connect($ftp_server);
if (!$conn) {
die("无法建立 SSL-FTP 连接到 $ftp_server");
}
echo "SSL-FTP 连接已建立\n";
// 登录(使用与普通 FTP 相同的 ftp_login 函数)
if (@ftp_login($conn, $ftp_user, $ftp_pass)) {
echo "登录成功\n";
} else {
die("登录失败");
}
// 启用被动模式(推荐用于 SSL 连接)
ftp_pasv($conn, true);
// 执行 FTP 操作...
$file_list = ftp_nlist($conn, ".");
if ($file_list) {
echo "远程目录中的文件:\n";
foreach ($file_list as $file) {
echo " - $file\n";
}
}
// 关闭连接
if (ftp_close($conn)) {
echo "连接已关闭\n";
}
?>
添加错误处理和 SSL 证书验证。
<?php
// 错误报告
error_reporting(E_ALL);
ini_set('display_errors', 1);
$ftp_server = "ftp.example.com";
$ftp_port = 21; // 或者 990 用于隐式 SSL
$ftp_user = "username";
$ftp_pass = "password";
// 建立连接,增加超时时间
$conn = @ftp_ssl_connect($ftp_server, $ftp_port, 30);
if ($conn === false) {
// 获取错误信息
$error = error_get_last();
echo "SSL-FTP 连接失败:\n";
echo "错误信息: " . ($error['message'] ?? '未知错误') . "\n";
// 尝试普通 FTP 连接作为回退
echo "尝试普通 FTP 连接...\n";
$conn = @ftp_connect($ftp_server, $ftp_port, 30);
if (!$conn) {
die("普通 FTP 连接也失败。请检查服务器和网络设置。");
} else {
echo "已建立普通 FTP 连接(未加密)\n";
}
}
// 登录
if (!@ftp_login($conn, $ftp_user, $ftp_pass)) {
ftp_close($conn);
die("FTP 登录失败");
}
echo "登录成功\n";
// 获取服务器系统类型
$system_type = ftp_systype($conn);
echo "服务器类型: " . ($system_type ?: '未知') . "\n";
// 关闭连接
ftp_close($conn);
?>
FTP over SSL 可以使用不同的端口(通常 21 用于显式 SSL,990 用于隐式 SSL)。
<?php
/**
* 尝试不同端口建立 SSL-FTP 连接
*/
function connect_ftps($hostname, $username, $password) {
// 尝试的端口列表
$ports = [21, 990, 22];
foreach ($ports as $port) {
echo "尝试连接 $hostname:$port ...\n";
// 尝试 SSL 连接
$conn = @ftp_ssl_connect($hostname, $port, 10);
if ($conn) {
echo "成功建立 SSL-FTP 连接到端口 $port\n";
// 尝试登录
if (@ftp_login($conn, $username, $password)) {
echo "登录成功\n";
return $conn; // 返回连接资源
} else {
echo "登录失败,关闭连接\n";
ftp_close($conn);
}
} else {
echo "端口 $port 连接失败\n";
}
}
// 如果所有 SSL 端口都失败,尝试普通 FTP
echo "尝试普通 FTP 连接...\n";
$conn = @ftp_connect($hostname, 21, 10);
if ($conn && @ftp_login($conn, $username, $password)) {
echo "已建立普通 FTP 连接(未加密)\n";
return $conn;
}
return false;
}
// 使用示例
$conn = connect_ftps("ftp.example.com", "username", "password");
if ($conn) {
// 执行 FTP 操作...
echo "当前目录: " . ftp_pwd($conn) . "\n";
// 列出文件
$files = ftp_nlist($conn, ".");
if ($files) {
echo "找到 " . count($files) . " 个文件/目录\n";
}
ftp_close($conn);
} else {
echo "无法建立任何类型的 FTP 连接\n";
}
?>
通过 SSL-FTP 连接上传和下载文件。
<?php
// 配置
$ftp_server = "ftp.example.com";
$ftp_user = "username";
$ftp_pass = "password";
$local_file = "local_file.txt";
$remote_file = "remote_file.txt";
// 建立 SSL-FTP 连接
$conn = ftp_ssl_connect($ftp_server);
if (!$conn) {
die("SSL-FTP 连接失败");
}
if (!ftp_login($conn, $ftp_user, $ftp_pass)) {
ftp_close($conn);
die("登录失败");
}
// 启用被动模式(对防火墙和 NAT 更友好)
ftp_pasv($conn, true);
// 上传文件
echo "上传文件...\n";
if (ftp_put($conn, $remote_file, $local_file, FTP_ASCII)) {
echo "文件上传成功: $local_file -> $remote_file\n";
} else {
echo "文件上传失败\n";
}
// 下载文件
echo "下载文件...\n";
if (ftp_get($conn, "downloaded_" . $local_file, $remote_file, FTP_ASCII)) {
echo "文件下载成功: $remote_file -> downloaded_$local_file\n";
} else {
echo "文件下载失败\n";
}
// 获取文件大小
$file_size = ftp_size($conn, $remote_file);
if ($file_size != -1) {
echo "远程文件大小: " . $file_size . " 字节\n";
}
// 关闭连接
ftp_close($conn);
echo "连接已关闭\n";
?>
ftp_ssl_connect() 被标记为已弃用。建议考虑使用 SFTP(通过 SSH2 扩展)或 FTPES。ftp_ssl_connect() 支持显式 SSL。ftp_pasv($conn, true)),因为主动模式在防火墙或 NAT 后可能无法正常工作。| 问题 | 可能的原因和解决方案 |
|---|---|
| 函数不存在 | PHP 没有启用 FTP 扩展或 OpenSSL 支持。重新编译 PHP 或安装必要的扩展。 |
| 连接失败 | 服务器不支持 SSL/TLS,或使用了错误的端口。尝试普通 FTP 连接或使用端口 990。 |
| 证书验证失败 | 服务器使用自签名或无效证书。可以考虑禁用证书验证(不推荐)或添加证书到信任链。 |
| 连接超时 | 网络问题或服务器响应慢。增加超时时间参数。 |
| 数据传输失败 | 防火墙阻止了 SSL-FTP 连接。尝试使用被动模式。 |
| PHP 7.0+ 中的弃用警告 | 函数被标记为已弃用。考虑迁移到 SFTP 或 FTPES。 |
由于 ftp_ssl_connect() 在 PHP 7.0+ 中已弃用,建议考虑以下替代方案:
使用 SSH2 扩展的 SFTP 功能:
<?php
// 需要 ssh2 扩展
if (extension_loaded('ssh2')) {
$connection = ssh2_connect('example.com', 22);
ssh2_auth_password($connection, 'username', 'password');
$sftp = ssh2_sftp($connection);
// 使用 SFTP 操作文件
$stream = fopen("ssh2.sftp://" . intval($sftp) . "/path/to/file", 'r');
}
?>
使用 cURL 扩展处理 FTPS:
<?php
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "ftps://example.com/file.txt");
curl_setopt($ch, CURLOPT_USERPWD, "username:password");
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false); // 仅测试使用
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false); // 仅测试使用
curl_setopt($ch, CURLOPT_FTP_SSL, CURLFTPSSL_TRY);
curl_setopt($ch, CURLOPT_FTPSSLAUTH, CURLFTPAUTH_DEFAULT);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
curl_close($ch);
?>
使用 Composer 安装的第三方 FTP/FTPS 库:
nicolab/php-ftp-clientleague/flysystem (带有 FTP 适配器)phpseclib/phpseclib (SFTP 支持)