PHP ftp_login() 函数
ftp_login() 函数用于登录到FTP服务器。
注意:在调用此函数之前,必须先使用ftp_connect()或ftp_ssl_connect()建立到FTP服务器的连接。
语法
ftp_login(resource $ftp_stream, string $username, string $password): bool
参数说明
| 参数 |
描述 |
$ftp_stream |
必需。FTP连接的资源标识符,由ftp_connect()或ftp_ssl_connect()函数返回。 |
$username |
必需。登录用户名。 |
$password |
必需。登录密码。 |
返回值
- 登录成功时返回
true
- 登录失败时返回
false
示例
示例1:基本使用
建立FTP连接并登录:
<?php
// FTP服务器信息
$ftp_server = "ftp.example.com";
$ftp_user = "username";
$ftp_pass = "password";
// 建立FTP连接
$conn_id = ftp_connect($ftp_server);
if ($conn_id === false) {
die("无法连接到FTP服务器: $ftp_server");
}
echo "已连接到FTP服务器\n";
// 登录FTP服务器
if (ftp_login($conn_id, $ftp_user, $ftp_pass)) {
echo "登录成功\n";
// 显示欢迎消息(某些FTP服务器支持)
echo ftp_systype($conn_id) . "\n";
// 获取当前目录
$current_dir = ftp_pwd($conn_id);
echo "当前目录: $current_dir\n";
// 执行其他操作...
} else {
echo "登录失败: 用户名或密码错误\n";
}
// 关闭连接
ftp_close($conn_id);
?>
示例2:安全的FTP连接器
<?php
/**
* 安全的FTP连接器类
*/
class SecureFTPConnector {
private $conn;
private $config;
private $is_connected = false;
private $is_logged_in = false;
public function __construct($config = []) {
$defaults = [
'host' => 'localhost',
'port' => 21,
'timeout' => 90,
'username' => 'anonymous',
'password' => 'guest@example.com',
'use_ssl' => false,
'passive_mode' => true,
'max_retries' => 3,
'retry_delay' => 2 // seconds
];
$this->config = array_merge($defaults, $config);
}
/**
* 连接到FTP服务器并登录
*/
public function connect() {
$retry_count = 0;
while ($retry_count < $this->config['max_retries']) {
try {
echo "尝试连接到 {$this->config['host']}:{$this->config['port']} (尝试 " . ($retry_count + 1) . ")...\n";
// 建立连接(SSL或普通)
if ($this->config['use_ssl']) {
$this->conn = ftp_ssl_connect(
$this->config['host'],
$this->config['port'],
$this->config['timeout']
);
} else {
$this->conn = ftp_connect(
$this->config['host'],
$this->config['port'],
$this->config['timeout']
);
}
if (!$this->conn) {
throw new Exception("无法连接到FTP服务器");
}
$this->is_connected = true;
// 登录
if (!ftp_login($this->conn, $this->config['username'], $this->config['password'])) {
throw new Exception("FTP登录失败: 用户名或密码错误");
}
$this->is_logged_in = true;
// 设置被动模式
if ($this->config['passive_mode']) {
ftp_pasv($this->conn, true);
}
echo "连接并登录成功\n";
$this->logConnection();
return true;
} catch (Exception $e) {
echo "连接失败: " . $e->getMessage() . "\n";
$retry_count++;
if ($retry_count < $this->config['max_retries']) {
echo "等待 {$this->config['retry_delay']} 秒后重试...\n";
sleep($this->config['retry_delay']);
}
}
}
return false;
}
/**
* 获取服务器信息
*/
public function getServerInfo() {
if (!$this->is_logged_in) {
throw new Exception("未登录到FTP服务器");
}
$info = [
'system_type' => @ftp_systype($this->conn),
'current_directory' => @ftp_pwd($this->conn),
'features' => [],
'connection_status' => $this->isConnected() ? '活动' : '断开'
];
// 尝试获取服务器特性
if (function_exists('ftp_raw')) {
$response = @ftp_raw($this->conn, "FEAT");
if ($response) {
foreach ($response as $line) {
if (preg_match('/^\s+([A-Z-]+)/', $line, $matches)) {
$info['features'][] = $matches[1];
}
}
}
}
return $info;
}
/**
* 测试连接
*/
public function testConnection() {
if (!$this->is_logged_in) {
return false;
}
try {
// 执行一个简单的命令来测试连接
$result = @ftp_pwd($this->conn);
return $result !== false;
} catch (Exception $e) {
return false;
}
}
/**
* 检查是否已连接
*/
public function isConnected() {
return $this->is_connected && is_resource($this->conn);
}
/**
* 检查是否已登录
*/
public function isLoggedIn() {
return $this->is_logged_in && $this->isConnected();
}
/**
* 获取FTP连接资源
*/
public function getConnection() {
if (!$this->is_logged_in) {
throw new Exception("未登录到FTP服务器");
}
return $this->conn;
}
/**
* 记录连接信息
*/
private function logConnection() {
$log_entry = [
'timestamp' => date('Y-m-d H:i:s'),
'host' => $this->config['host'],
'port' => $this->config['port'],
'username' => $this->config['username'],
'use_ssl' => $this->config['use_ssl'],
'success' => true
];
// 这里可以保存到文件或数据库
error_log("[FTP_LOGIN] " . json_encode($log_entry));
}
/**
* 关闭连接
*/
public function close() {
if ($this->is_connected && is_resource($this->conn)) {
ftp_close($this->conn);
$this->conn = null;
$this->is_connected = false;
$this->is_logged_in = false;
echo "FTP连接已关闭\n";
}
}
public function __destruct() {
$this->close();
}
}
// 使用示例
try {
// 创建安全连接器
$ftp = new SecureFTPConnector([
'host' => 'ftp.example.com',
'port' => 21,
'username' => 'myusername',
'password' => 'mypassword',
'use_ssl' => false,
'passive_mode' => true,
'max_retries' => 3
]);
// 连接并登录
if ($ftp->connect()) {
// 获取服务器信息
$info = $ftp->getServerInfo();
echo "\n服务器信息:\n";
echo "系统类型: " . ($info['system_type'] ?: '未知') . "\n";
echo "当前目录: " . $info['current_directory'] . "\n";
echo "连接状态: " . $info['connection_status'] . "\n";
if (!empty($info['features'])) {
echo "支持的特性: " . implode(', ', $info['features']) . "\n";
}
// 测试连接
echo "\n连接测试: " . ($ftp->testConnection() ? "成功" : "失败") . "\n";
// 可以继续执行其他操作...
}
// 会自动关闭连接
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . "\n";
}
?>
示例3:匿名登录和认证登录处理
<?php
/**
* FTP登录管理器(支持匿名和认证登录)
*/
class FTPLoginManager {
private $conn;
private $login_type = 'anonymous'; // anonymous 或 authenticated
/**
* 尝试多种方式登录
*/
public function connectWithFallback($host, $options = []) {
$defaults = [
'port' => 21,
'timeout' => 30,
'username' => null,
'password' => null,
'try_anonymous' => true,
'anonymous_email' => 'guest@example.com'
];
$options = array_merge($defaults, $options);
// 建立连接
$this->conn = ftp_connect($host, $options['port'], $options['timeout']);
if (!$this->conn) {
throw new Exception("无法连接到FTP服务器: $host");
}
echo "已连接到FTP服务器: $host\n";
// 尝试认证登录
if ($options['username'] && $options['password']) {
if (ftp_login($this->conn, $options['username'], $options['password'])) {
$this->login_type = 'authenticated';
echo "认证登录成功: {$options['username']}\n";
return true;
} else {
echo "认证登录失败\n";
}
}
// 尝试匿名登录
if ($options['try_anonymous']) {
if (ftp_login($this->conn, 'anonymous', $options['anonymous_email'])) {
$this->login_type = 'anonymous';
echo "匿名登录成功\n";
// 匿名登录通常有限制,检查权限
$this->checkAnonymousPermissions();
return true;
} else {
echo "匿名登录失败\n";
}
}
ftp_close($this->conn);
throw new Exception("所有登录方式都失败");
}
/**
* 检查匿名登录权限
*/
private function checkAnonymousPermissions() {
echo "检查匿名登录权限...\n";
try {
// 尝试获取当前目录
$pwd = ftp_pwd($this->conn);
echo "当前目录: $pwd\n";
// 尝试列出文件
$files = ftp_nlist($this->conn, ".");
if ($files !== false) {
echo "可列出文件数量: " . count($files) . "\n";
} else {
echo "无法列出文件(权限不足)\n";
}
// 尝试创建目录(通常会失败)
$test_dir = "test_dir_" . time();
if (@ftp_mkdir($this->conn, $test_dir)) {
echo "可以创建目录(不寻常的匿名权限)\n";
ftp_rmdir($this->conn, $test_dir); // 清理
} else {
echo "无法创建目录(正常匿名权限)\n";
}
} catch (Exception $e) {
echo "权限检查错误: " . $e->getMessage() . "\n";
}
}
/**
* 获取登录类型
*/
public function getLoginType() {
return $this->login_type;
}
/**
* 获取连接资源
*/
public function getConnection() {
if (!$this->conn) {
throw new Exception("未连接到FTP服务器");
}
return $this->conn;
}
/**
* 关闭连接
*/
public function close() {
if (is_resource($this->conn)) {
ftp_close($this->conn);
$this->conn = null;
echo "FTP连接已关闭\n";
}
}
}
// 使用示例
try {
$loginManager = new FTPLoginManager();
echo "=== 场景1: 认证登录 ===\n";
try {
$loginManager->connectWithFallback('ftp.example.com', [
'username' => 'myusername',
'password' => 'mypassword',
'try_anonymous' => false
]);
echo "登录类型: " . $loginManager->getLoginType() . "\n";
$loginManager->close();
} catch (Exception $e) {
echo "场景1失败: " . $e->getMessage() . "\n";
}
echo "\n=== 场景2: 匿名登录 ===\n";
try {
$loginManager->connectWithFallback('ftp.gnu.org', [
'username' => null,
'password' => null,
'try_anonymous' => true,
'anonymous_email' => 'me@example.com'
]);
echo "登录类型: " . $loginManager->getLoginType() . "\n";
// 使用连接执行操作
$conn = $loginManager->getConnection();
$files = ftp_nlist($conn, ".");
echo "根目录文件数: " . count($files) . "\n";
$loginManager->close();
} catch (Exception $e) {
echo "场景2失败: " . $e->getMessage() . "\n";
}
echo "\n=== 场景3: 自动回退 ===\n";
try {
$loginManager->connectWithFallback('ftp.example.com', [
'username' => 'wronguser', // 错误的用户名
'password' => 'wrongpass', // 错误的密码
'try_anonymous' => true // 认证失败后尝试匿名
]);
echo "登录类型: " . $loginManager->getLoginType() . "\n";
$loginManager->close();
} catch (Exception $e) {
echo "场景3失败: " . $e->getMessage() . "\n";
}
} catch (Exception $e) {
echo "总体错误: " . $e->getMessage() . "\n";
}
?>
示例4:Web界面的FTP登录表单
<?php
// Web界面FTP登录
session_start();
// 处理登录请求
if ($_SERVER['REQUEST_METHOD'] === 'POST') {
$host = $_POST['host'] ?? '';
$port = $_POST['port'] ?? 21;
$username = $_POST['username'] ?? '';
$password = $_POST['password'] ?? '';
$use_ssl = isset($_POST['use_ssl']) ? true : false;
// 验证输入
$errors = [];
if (empty($host)) {
$errors[] = '主机名不能为空';
}
if (!is_numeric($port) || $port < 1 || $port > 65535) {
$errors[] = '端口号无效';
}
if (empty($errors)) {
// 尝试连接
$start_time = microtime(true);
if ($use_ssl && function_exists('ftp_ssl_connect')) {
$conn = ftp_ssl_connect($host, $port, 10);
} else {
$conn = ftp_connect($host, $port, 10);
}
if ($conn) {
// 尝试登录
if (ftp_login($conn, $username, $password)) {
$end_time = microtime(true);
$connection_time = round(($end_time - $start_time) * 1000, 2);
// 保存连接信息到会话
$_SESSION['ftp_connection'] = [
'host' => $host,
'port' => $port,
'username' => $username,
'use_ssl' => $use_ssl,
'conn_time' => $connection_time,
'logged_in_at' => date('Y-m-d H:i:s')
];
// 保存连接资源标识符(注意:资源不能直接序列化)
$_SESSION['ftp_conn_id'] = null;
// 在实际应用中,可能需要将连接保持在其他存储中
// 重定向到文件管理器
header('Location: ftp_file_manager.php');
exit;
} else {
$errors[] = '登录失败:用户名或密码错误';
}
ftp_close($conn);
} else {
$errors[] = '无法连接到FTP服务器';
}
}
// 如果有错误,保存到会话
if (!empty($errors)) {
$_SESSION['ftp_errors'] = $errors;
header('Location: ' . $_SERVER['PHP_SELF']);
exit;
}
}
// 显示错误信息
$errors = $_SESSION['ftp_errors'] ?? [];
unset($_SESSION['ftp_errors']);
?>
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>FTP登录</title>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<style>
.login-container {
max-width: 500px;
margin: 50px auto;
padding: 30px;
border-radius: 10px;
box-shadow: 0 0 20px rgba(0,0,0,0.1);
background-color: white;
}
.login-header {
text-align: center;
margin-bottom: 30px;
}
.login-header i {
font-size: 3em;
color: #0d6efd;
margin-bottom: 15px;
}
.error-message {
animation: fadeIn 0.5s;
}
@keyframes fadeIn {
from { opacity: 0; transform: translateY(-10px); }
to { opacity: 1; transform: translateY(0); }
}
.form-label {
font-weight: 500;
}
.remember-me {
display: flex;
align-items: center;
justify-content: space-between;
}
</style>
</head>
<body style="background: linear-gradient(135deg, #667eea 0%, #764ba2 100%); min-height: 100vh;">
<div class="login-container">
<div class="login-header">
<i class="fas fa-server"></i>
<h1>FTP登录</h1>
<p class="text-muted">连接到远程FTP服务器</p>
</div>
<?php if (!empty($errors)): ?>
<div class="alert alert-danger error-message">
<h5><i class="fas fa-exclamation-triangle me-2"></i>登录失败</h5>
<ul class="mb-0">
<?php foreach ($errors as $error): ?>
<li><?php echo htmlspecialchars($error); ?></li>
<?php endforeach; ?>
</ul>
</div>
<?php endif; ?>
<form method="post" action="">
<div class="mb-3">
<label for="host" class="form-label"><i class="fas fa-globe me-2"></i>FTP服务器</label>
<input type="text" class="form-control" id="host" name="host"
placeholder="例如: ftp.example.com" required
value="<?php echo htmlspecialchars($_POST['host'] ?? ''); ?>">
<div class="form-text">输入FTP服务器的主机名或IP地址</div>
</div>
<div class="row mb-3">
<div class="col-md-6">
<label for="port" class="form-label"><i class="fas fa-plug me-2"></i>端口</label>
<input type="number" class="form-control" id="port" name="port"
min="1" max="65535" value="<?php echo htmlspecialchars($_POST['port'] ?? '21'); ?>" required>
<div class="form-text">默认端口: 21</div>
</div>
<div class="col-md-6">
<label for="username" class="form-label"><i class="fas fa-user me-2"></i>用户名</label>
<input type="text" class="form-control" id="username" name="username"
placeholder="输入用户名"
value="<?php echo htmlspecialchars($_POST['username'] ?? ''); ?>" required>
<div class="form-text">匿名登录使用: anonymous</div>
</div>
</div>
<div class="mb-3">
<label for="password" class="form-label"><i class="fas fa-key me-2"></i>密码</label>
<input type="password" class="form-control" id="password" name="password"
placeholder="输入密码" required>
<div class="form-text">匿名登录密码通常为你的邮箱地址</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="use_ssl" name="use_ssl"
<?php echo isset($_POST['use_ssl']) ? 'checked' : ''; ?>>
<label class="form-check-label" for="use_ssl">
<i class="fas fa-lock me-1"></i>使用SSL安全连接 (FTPS)
</label>
<div class="form-text">启用加密连接以保护数据传输</div>
</div>
<div class="mb-3 form-check">
<input type="checkbox" class="form-check-input" id="remember" name="remember">
<label class="form-check-label" for="remember">记住我</label>
</div>
<div class="d-grid gap-2">
<button type="submit" class="btn btn-primary btn-lg">
<i class="fas fa-sign-in-alt me-2"></i>登录
</button>
<button type="reset" class="btn btn-outline-secondary">
<i class="fas fa-redo me-2"></i>重置
</button>
</div>
</form>
<div class="mt-4 text-center">
<hr>
<p class="text-muted small">
<i class="fas fa-info-circle me-1"></i>
常用FTP服务器示例:
<br>
<code>ftp.gnu.org</code> (匿名登录) |
<code>ftp.debian.org</code> (匿名登录) |
<code>ftp.mozilla.org</code> (匿名登录)
</p>
</div>
</div>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.bundle.min.js"></script>
<script>
document.addEventListener('DOMContentLoaded', function() {
// 自动填充示例
const exampleServers = [
{host: 'ftp.gnu.org', port: 21, username: 'anonymous', ssl: false},
{host: 'ftp.debian.org', port: 21, username: 'anonymous', ssl: false},
{host: 'ftp.mozilla.org', port: 21, username: 'anonymous', ssl: false}
];
// 添加示例选择下拉框
const hostInput = document.getElementById('host');
const usernameInput = document.getElementById('username');
const portInput = document.getElementById('port');
const sslCheckbox = document.getElementById('use_ssl');
// 创建示例选择器
const exampleSelector = document.createElement('select');
exampleSelector.className = 'form-select mb-2';
exampleSelector.innerHTML = `
<option value="">选择示例服务器...</option>
<option value="gnu">GNU FTP服务器 (匿名)</option>
<option value="debian">Debian FTP服务器 (匿名)</option>
<option value="mozilla">Mozilla FTP服务器 (匿名)</option>
<option value="custom">自定义服务器</option>
`;
hostInput.parentNode.insertBefore(exampleSelector, hostInput);
exampleSelector.addEventListener('change', function() {
const value = this.value;
if (value === 'gnu') {
fillExample(exampleServers[0]);
} else if (value === 'debian') {
fillExample(exampleServers[1]);
} else if (value === 'mozilla') {
fillExample(exampleServers[2]);
} else if (value === 'custom') {
clearFields();
}
});
function fillExample(server) {
hostInput.value = server.host;
portInput.value = server.port;
usernameInput.value = server.username;
sslCheckbox.checked = server.ssl;
// 密码字段提示
const passwordInput = document.getElementById('password');
passwordInput.placeholder = '匿名登录请输入你的邮箱地址';
passwordInput.focus();
}
function clearFields() {
hostInput.value = '';
usernameInput.value = '';
portInput.value = '21';
sslCheckbox.checked = false;
document.getElementById('password').placeholder = '输入密码';
}
// 表单验证
const form = document.querySelector('form');
form.addEventListener('submit', function(e) {
const host = hostInput.value.trim();
const port = parseInt(portInput.value);
if (!host) {
e.preventDefault();
alert('请输入FTP服务器地址');
hostInput.focus();
return false;
}
if (isNaN(port) || port < 1 || port > 65535) {
e.preventDefault();
alert('请输入有效的端口号 (1-65535)');
portInput.focus();
return false;
}
// 显示加载状态
const submitBtn = form.querySelector('button[type="submit"]');
const originalText = submitBtn.innerHTML;
submitBtn.innerHTML = '<i class="fas fa-spinner fa-spin me-2"></i>正在连接...';
submitBtn.disabled = true;
return true;
});
});
</script>
</body>
</html>
示例5:连接池和会话管理
<?php
/**
* FTP连接池管理器
*/
class FTPConnectionPool {
private static $instance = null;
private $connections = [];
private $max_pool_size = 5;
private $connection_timeout = 300; // 5分钟
private function __construct() {
// 私有构造函数,单例模式
}
public static function getInstance() {
if (self::$instance === null) {
self::$instance = new self();
}
return self::$instance;
}
/**
* 获取FTP连接
*/
public function getConnection($host, $username, $password, $port = 21, $use_ssl = false) {
$connection_key = $this->getConnectionKey($host, $username, $port);
// 检查连接池中是否有可用的连接
if (isset($this->connections[$connection_key])) {
foreach ($this->connections[$connection_key] as $index => $connection) {
// 检查连接是否仍然有效
if ($this->isConnectionValid($connection['conn'])) {
// 检查连接是否过期
if (time() - $connection['last_used'] < $this->connection_timeout) {
$conn = array_splice($this->connections[$connection_key], $index, 1)[0];
$conn['last_used'] = time();
echo "从连接池获取现有连接\n";
return $conn['conn'];
}
}
}
}
// 没有可用连接,创建新连接
echo "创建新的FTP连接\n";
return $this->createNewConnection($host, $username, $password, $port, $use_ssl);
}
/**
* 归还连接到池中
*/
public function returnConnection($host, $username, $port, $conn) {
if (!is_resource($conn)) {
echo "连接无效,不归还到池中\n";
return;
}
$connection_key = $this->getConnectionKey($host, $username, $port);
if (!isset($this->connections[$connection_key])) {
$this->connections[$connection_key] = [];
}
// 检查连接池是否已满
if (count($this->connections[$connection_key]) >= $this->max_pool_size) {
echo "连接池已满,关闭连接\n";
ftp_close($conn);
return;
}
// 将连接放回池中
$this->connections[$connection_key][] = [
'conn' => $conn,
'last_used' => time(),
'created_at' => time()
];
echo "连接已归还到连接池\n";
}
/**
* 创建新连接
*/
private function createNewConnection($host, $username, $password, $port, $use_ssl) {
// 建立连接
if ($use_ssl && function_exists('ftp_ssl_connect')) {
$conn = ftp_ssl_connect($host, $port, 30);
} else {
$conn = ftp_connect($host, $port, 30);
}
if (!$conn) {
throw new Exception("无法连接到FTP服务器: $host");
}
// 登录
if (!ftp_login($conn, $username, $password)) {
ftp_close($conn);
throw new Exception("FTP登录失败");
}
// 开启被动模式
ftp_pasv($conn, true);
return $conn;
}
/**
* 检查连接是否有效
*/
private function isConnectionValid($conn) {
if (!is_resource($conn)) {
return false;
}
try {
$result = @ftp_pwd($conn);
return $result !== false;
} catch (Exception $e) {
return false;
}
}
/**
* 生成连接键
*/
private function getConnectionKey($host, $username, $port) {
return md5("$host:$port:$username");
}
/**
* 清理过期连接
*/
public function cleanupExpiredConnections() {
$cleaned_count = 0;
foreach ($this->connections as $key => $pool) {
foreach ($pool as $index => $connection) {
if (time() - $connection['last_used'] > $this->connection_timeout) {
if (is_resource($connection['conn'])) {
ftp_close($connection['conn']);
}
unset($this->connections[$key][$index]);
$cleaned_count++;
}
}
// 重新索引数组
$this->connections[$key] = array_values($this->connections[$key]);
// 如果池为空,移除键
if (empty($this->connections[$key])) {
unset($this->connections[$key]);
}
}
echo "清理了 {$cleaned_count} 个过期连接\n";
return $cleaned_count;
}
/**
* 获取连接池状态
*/
public function getPoolStatus() {
$status = [
'total_pools' => count($this->connections),
'total_connections' => 0,
'pools' => []
];
foreach ($this->connections as $key => $pool) {
$status['total_connections'] += count($pool);
$status['pools'][$key] = [
'connections' => count($pool),
'oldest' => time() - min(array_column($pool, 'created_at')),
'newest' => time() - max(array_column($pool, 'created_at'))
];
}
return $status;
}
/**
* 关闭所有连接
*/
public function closeAllConnections() {
$closed_count = 0;
foreach ($this->connections as $key => $pool) {
foreach ($pool as $connection) {
if (is_resource($connection['conn'])) {
ftp_close($connection['conn']);
$closed_count++;
}
}
}
$this->connections = [];
echo "关闭了 {$closed_count} 个连接\n";
return $closed_count;
}
}
// 使用示例
try {
$pool = FTPConnectionPool::getInstance();
// 模拟多个并发请求
$operations = [
['op' => 'download', 'file' => 'file1.txt'],
['op' => 'upload', 'file' => 'file2.txt'],
['op' => 'list', 'dir' => '/'],
['op' => 'delete', 'file' => 'old.txt']
];
foreach ($operations as $operation) {
echo "\n执行操作: {$operation['op']} - {$operation['file']}\n";
// 从连接池获取连接
$conn = $pool->getConnection(
'ftp.example.com',
'username',
'password'
);
// 模拟操作
echo "正在执行 {$operation['op']} 操作...\n";
sleep(1); // 模拟耗时操作
// 归还连接到池中
$pool->returnConnection('ftp.example.com', 'username', 21, $conn);
}
// 查看连接池状态
echo "\n连接池状态:\n";
$status = $pool->getPoolStatus();
echo "连接池数量: {$status['total_pools']}\n";
echo "总连接数: {$status['total_connections']}\n";
// 清理过期连接
echo "\n清理过期连接:\n";
$cleaned = $pool->cleanupExpiredConnections();
echo "清理了 {$cleaned} 个连接\n";
// 关闭所有连接
echo "\n关闭所有连接:\n";
$closed = $pool->closeAllConnections();
echo "关闭了 {$closed} 个连接\n";
} catch (Exception $e) {
echo "错误: " . $e->getMessage() . "\n";
}
?>
常见错误和解决方案
常见登录问题:
| 错误现象 |
可能原因 |
解决方案 |
| 登录失败 |
用户名或密码错误 |
检查凭据,尝试匿名登录(anonymous/email@example.com) |
| 连接成功但登录失败 |
FTP服务未运行或配置错误 |
确认FTP服务正在运行,检查服务器配置 |
| SSL连接失败 |
服务器不支持SSL或证书问题 |
尝试普通连接,检查SSL证书 |
| 登录后权限不足 |
用户权限限制 |
检查用户权限设置,联系服务器管理员 |
| 连接超时 |
网络问题或服务器无响应 |
检查网络连接,增加超时时间 |
安全最佳实践
安全建议:
- 使用强密码,定期更换FTP密码
- 尽可能使用SSL/TLS加密连接(FTPS)
- 避免在代码中硬编码密码,使用配置文件或环境变量
- 限制FTP用户的权限,遵循最小权限原则
- 定期检查登录日志,监控异常登录行为
- 考虑使用SSH密钥认证替代密码认证
- 使用防火墙限制FTP访问来源IP
常见问题
| 登录类型 |
用户名 |
密码 |
权限 |
用途 |
| 匿名登录 |
anonymous |
邮箱地址(如user@example.com) |
通常只读,有限权限 |
公开文件下载,公共资源访问 |
| 认证登录 |
服务器分配的用户名 |
用户设置的密码 |
根据用户配置的权限 |
文件管理,网站维护,数据备份 |
<?php
function debugFTPLogin($host, $username, $password, $port = 21) {
echo "开始FTP登录调试...\n";
echo "主机: $host\n";
echo "端口: $port\n";
echo "用户名: $username\n";
// 测试连接
$conn = @ftp_connect($host, $port, 10);
if (!$conn) {
echo "❌ 连接失败\n";
// 检查网络
echo "网络测试:\n";
$ping_result = @fsockopen($host, $port, $errno, $errstr, 10);
if ($ping_result) {
echo " ✓ 端口 $port 可达\n";
fclose($ping_result);
} else {
echo " ✗ 端口 $port 不可达: $errstr\n";
}
return false;
}
echo "✓ 连接成功\n";
// 测试登录
if (!@ftp_login($conn, $username, $password)) {
echo "❌ 登录失败\n";
// 测试匿名登录
echo "尝试匿名登录...\n";
if (@ftp_login($conn, 'anonymous', 'guest@example.com')) {
echo " ✓ 匿名登录成功\n";
echo " 问题: 认证凭据错误或用户不存在\n";
} else {
echo " ✗ 匿名登录也失败\n";
echo " 问题: 服务器可能禁用了该用户名或所有登录\n";
}
ftp_close($conn);
return false;
}
echo "✓ 登录成功\n";
// 获取服务器信息
$system = @ftp_systype($conn);
$pwd = @ftp_pwd($conn);
echo "系统类型: " . ($system ?: '未知') . "\n";
echo "当前目录: " . ($pwd ?: '未知') . "\n";
ftp_close($conn);
return true;
}
// 使用示例
debugFTPLogin('ftp.example.com', 'myuser', 'mypass');
?>
| 协议 |
端口 |
加密 |
认证方式 |
安全性 |
| FTP |
21 |
无(或通过FTPS) |
用户名/密码 |
低(除非使用FTPS) |
| SFTP (SSH) |
22 |
是(SSH加密) |
用户名/密码或密钥 |
高 |
建议:对于敏感数据传输,推荐使用SFTP代替FTP。SFTP提供更好的安全性和更多的功能。
相关函数
| 函数 |
描述 |
ftp_connect() |
建立FTP连接 |
ftp_ssl_connect() |
建立SSL加密的FTP连接 |
ftp_close() |
关闭FTP连接 |
ftp_pasv() |
开启或关闭被动模式 |
ssh2_connect() |
建立SSH连接(用于SFTP) |
ssh2_auth_password() |
SSH密码认证 |