本文目录导读:

我来为您封装一个完整的PHP FTP操作类,包含常用的文件上传、下载、目录操作等功能:
<?php
/**
* PHP FTP操作类
* 支持文件上传、下载、目录操作等常用功能
*/
class FtpClient {
/**
* FTP连接句柄
* @var resource
*/
private $conn;
/**
* FTP连接状态
* @var bool
*/
private $isConnected = false;
/**
* 默认被动模式
* @var bool
*/
private $passiveMode = true;
/**
* 超时时间(秒)
* @var int
*/
private $timeout = 90;
/**
* 构造函数
* @param string $host FTP服务器地址
* @param string $username 用户名
* @param string $password 密码
* @param int $port FTP端口,默认21
* @param int $timeout 超时时间
*/
public function __construct($host, $username, $password, $port = 21, $timeout = 90) {
$this->timeout = $timeout;
$this->connect($host, $username, $password, $port);
}
/**
* 连接FTP服务器
* @param string $host FTP服务器地址
* @param string $username 用户名
* @param string $password 密码
* @param int $port FTP端口
* @return bool 连接成功返回true,失败返回false
*/
public function connect($host, $username, $password, $port = 21) {
// 连接FTP服务器
$this->conn = @ftp_connect($host, $port, $this->timeout);
if (!$this->conn) {
throw new Exception("无法连接到FTP服务器: $host:$port");
}
// 登录FTP服务器
$login = @ftp_login($this->conn, $username, $password);
if (!$login) {
$this->close();
throw new Exception("FTP登录失败,请检查用户名和密码");
}
$this->isConnected = true;
// 设置被动模式
if ($this->passiveMode) {
$this->setPassiveMode(true);
}
return true;
}
/**
* 设置被动模式
* @param bool $mode true为被动模式,false为主动模式
*/
public function setPassiveMode($mode = true) {
if ($this->isConnected) {
ftp_pasv($this->conn, $mode);
}
}
/**
* 检查是否已连接
* @return bool
*/
public function isConnected() {
return $this->isConnected;
}
/**
* 上传文件
* @param string $localFile 本地文件路径
* @param string $remoteFile 远程文件路径
* @param string $mode 传输模式(FTP_ASCII 或 FTP_BINARY)
* @return bool 上传成功返回true
*/
public function upload($localFile, $remoteFile, $mode = FTP_BINARY) {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
if (!file_exists($localFile)) {
throw new Exception("本地文件不存在: " . $localFile);
}
// 确保远程目录存在
$remoteDir = dirname($remoteFile);
if (!$this->directoryExists($remoteDir)) {
$this->createDirectory($remoteDir, true);
}
return @ftp_put($this->conn, $remoteFile, $localFile, $mode);
}
/**
* 上传文件(使用文件名和内容)
* @param string $remoteFile 远程文件路径
* @param string $content 文件内容
* @param string $mode 传输模式
* @return bool 上传成功返回true
*/
public function uploadContent($remoteFile, $content, $mode = FTP_BINARY) {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
// 创建临时文件
$tempFile = tempnam(sys_get_temp_dir(), 'ftp_');
file_put_contents($tempFile, $content);
try {
// 确保远程目录存在
$remoteDir = dirname($remoteFile);
if (!$this->directoryExists($remoteDir)) {
$this->createDirectory($remoteDir, true);
}
$result = @ftp_put($this->conn, $remoteFile, $tempFile, $mode);
unlink($tempFile); // 删除临时文件
return $result;
} catch (Exception $e) {
unlink($tempFile); // 异常时也删除临时文件
throw $e;
}
}
/**
* 下载文件
* @param string $remoteFile 远程文件路径
* @param string $localFile 本地保存路径
* @param string $mode 传输模式
* @return bool 下载成功返回true
*/
public function download($remoteFile, $localFile, $mode = FTP_BINARY) {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
return @ftp_get($this->conn, $localFile, $remoteFile, $mode);
}
/**
* 获取远程文件内容
* @param string $remoteFile 远程文件路径
* @return string|bool 文件内容或false
*/
public function getFileContent($remoteFile) {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
// 创建临时文件
$tempFile = tempnam(sys_get_temp_dir(), 'ftp_content_');
$result = @ftp_get($this->conn, $tempFile, $remoteFile, FTP_BINARY);
if ($result) {
$content = file_get_contents($tempFile);
unlink($tempFile);
return $content;
}
unlink($tempFile);
return false;
}
/**
* 删除远程文件
* @param string $remoteFile 远程文件路径
* @return bool 删除成功返回true
*/
public function deleteFile($remoteFile) {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
return @ftp_delete($this->conn, $remoteFile);
}
/**
* 重命名文件
* @param string $oldName 原文件名
* @param string $newName 新文件名
* @return bool 重命名成功返回true
*/
public function rename($oldName, $newName) {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
return @ftp_rename($this->conn, $oldName, $newName);
}
/**
* 创建目录
* @param string $directory 目录路径
* @param bool $recursive 是否递归创建
* @return bool 创建成功返回true
*/
public function createDirectory($directory, $recursive = false) {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
if ($recursive) {
// 递归创建目录
$dirs = explode('/', $directory);
$current = '';
foreach ($dirs as $dir) {
if (empty($dir)) continue;
$current .= $dir . '/';
if (!$this->directoryExists($current)) {
if (!@ftp_mkdir($this->conn, $current)) {
return false;
}
}
}
return true;
}
return @ftp_mkdir($this->conn, $directory);
}
/**
* 删除目录
* @param string $directory 目录路径
* @return bool 删除成功返回true
*/
public function deleteDirectory($directory) {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
return @ftp_rmdir($this->conn, $directory);
}
/**
* 检查目录是否存在
* @param string $directory 目录路径
* @return bool 目录存在返回true
*/
public function directoryExists($directory) {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
$currentDir = $this->getCurrentDirectory();
if (@ftp_chdir($this->conn, $directory)) {
// 切换回原目录
@ftp_chdir($this->conn, $currentDir);
return true;
}
return false;
}
/**
* 改变当前目录
* @param string $directory 目录路径
* @return bool 成功返回true
*/
public function changeDirectory($directory) {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
return @ftp_chdir($this->conn, $directory);
}
/**
* 获取当前目录
* @return string|bool 当前目录路径或false
*/
public function getCurrentDirectory() {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
return @ftp_pwd($this->conn);
}
/**
* 列出目录内容
* @param string $directory 目录路径
* @param bool $details 是否包含详细信息
* @return array|bool 文件列表数组或false
*/
public function listFiles($directory = '.', $details = false) {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
if ($details) {
return @ftp_rawlist($this->conn, $directory);
}
return @ftp_nlist($this->conn, $directory);
}
/**
* 获取文件大小
* @param string $remoteFile 远程文件路径
* @return int|bool 文件大小(字节)或false
*/
public function getFileSize($remoteFile) {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
return @ftp_size($this->conn, $remoteFile);
}
/**
* 获取文件的修改时间
* @param string $remoteFile 远程文件路径
* @return int|bool 时间戳或false
*/
public function getModificationTime($remoteFile) {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
return @ftp_mdtm($this->conn, $remoteFile);
}
/**
* 执行FTP命令
* @param string $command FTP命令
* @return mixed 命令执行结果
*/
public function executeCommand($command) {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
return @ftp_exec($this->conn, $command);
}
/**
* 关闭FTP连接
* @return bool 关闭成功返回true
*/
public function close() {
if ($this->isConnected && $this->conn) {
$this->isConnected = false;
return @ftp_close($this->conn);
}
return true;
}
/**
* 析构函数
*/
public function __destruct() {
$this->close();
}
}
使用示例
<?php
// 引入类文件
require_once 'FtpClient.php';
try {
// 创建FTP连接
$ftp = new FtpClient(
'ftp.example.com', // FTP服务器地址
'username', // 用户名
'password', // 密码
21, // 端口
90 // 超时时间
);
echo "FTP连接成功!<br>";
// 1. 上传文件
$uploadResult = $ftp->upload(
'/local/path/to/file.txt', // 本地文件
'/remote/path/file.txt' // 远程路径
);
if ($uploadResult) {
echo "文件上传成功<br>";
} else {
echo "文件上传失败<br>";
}
// 2. 上传内容(不创建本地文件)
$contentResult = $ftp->uploadContent(
'/remote/path/content.txt',
"这是要上传的内容"
);
// 3. 下载文件
$downloadResult = $ftp->download(
'/remote/path/file.txt',
'/local/path/downloaded.txt'
);
// 4. 获取远程文件内容
$content = $ftp->getFileContent('/remote/path/file.txt');
// 5. 创建目录(递归)
$ftp->createDirectory('/remote/path/sub/dir', true);
// 6. 列出文件
$files = $ftp->listFiles('/remote/path');
// 7. 删除文件
$ftp->deleteFile('/remote/path/delete.txt');
// 8. 重命名文件
$ftp->rename('/remote/path/old.txt', '/remote/path/new.txt');
// 9. 获取文件信息
$size = $ftp->getFileSize('/remote/path/large.zip');
$mtime = $ftp->getModificationTime('/remote/path/file.txt');
echo "文件大小: {$size} 字节<br>";
echo "文件修改时间: " . date('Y-m-d H:i:s', $mtime) . "<br>";
// 10. 关闭连接
$ftp->close();
} catch (Exception $e) {
echo "错误: " . $e->getMessage();
}
?>
增强功能补充
如果需要更多功能,可以补充以下方法:
<?php
// 在FtpClient类中添加以下方法
/**
* 批量上传文件
* @param array $files 文件映射数组 ['local_path' => 'remote_path']
* @return array 上传结果
*/
public function batchUpload($files) {
$results = [];
foreach ($files as $local => $remote) {
try {
$results[] = [
'file' => $local,
'success' => $this->upload($local, $remote)
];
} catch (Exception $e) {
$results[] = [
'file' => $local,
'success' => false,
'error' => $e->getMessage()
];
}
}
return $results;
}
/**
* 批量下载文件
* @param array $files 文件映射数组 ['remote_path' => 'local_path']
* @return array 下载结果
*/
public function batchDownload($files) {
$results = [];
foreach ($files as $remote => $local) {
try {
$results[] = [
'file' => $remote,
'success' => $this->download($remote, $local)
];
} catch (Exception $e) {
$results[] = [
'file' => $remote,
'success' => false,
'error' => $e->getMessage()
];
}
}
return $results;
}
/**
* 递归删除目录及内容
* @param string $directory 目录路径
* @return bool 删除成功返回true
*/
public function deleteDirectoryRecursive($directory) {
// 首先删除目录中的所有文件
$files = $this->listFiles($directory);
if (is_array($files)) {
foreach ($files as $file) {
// 跳过 . 和 ..
if ($file === '.' || $file === '..') continue;
// 构建完整路径
$path = rtrim($directory, '/') . '/' . basename($file);
// 如果是目录,递归删除
if ($this->directoryExists($path)) {
$this->deleteDirectoryRecursive($path);
} else {
// 如果是文件,直接删除
$this->deleteFile($path);
}
}
}
// 最后删除目录本身
return $this->deleteDirectory($directory);
}
/**
* 上传整个目录
* @param string $localDir 本地目录
* @param string $remoteDir 远程目录
* @return bool 上传成功返回true
*/
public function uploadDirectory($localDir, $remoteDir) {
// 创建远程目录
if (!$this->directoryExists($remoteDir)) {
$this->createDirectory($remoteDir, true);
}
// 获取本地目录内容
$items = scandir($localDir);
foreach ($items as $item) {
if ($item === '.' || $item === '..') continue;
$localPath = $localDir . '/' . $item;
$remotePath = $remoteDir . '/' . $item;
if (is_dir($localPath)) {
// 递归上传子目录
$this->uploadDirectory($localPath, $remotePath);
} else {
// 上传文件
$this->upload($localPath, $remotePath);
}
}
return true;
}
/**
* 设置文件权限
* @param string $remoteFile 远程文件路径
* @param int $permission 权限值(如:0644)
* @return bool 设置成功返回true
*/
public function setPermission($remoteFile, $permission) {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
return @ftp_chmod($this->conn, $permission, $remoteFile);
}
/**
* 获取FTP服务器信息
* @return string 服务器信息
*/
public function getSystemInfo() {
if (!$this->isConnected) {
throw new Exception("FTP未连接");
}
return @ftp_systype($this->conn);
}
这个FTP类封装了PHP中所有常用的FTP函数,并提供了更多的便捷方法,包括:
- 连接管理:连接、断开、状态检查
- 文件操作:上传、下载、删除、重命名
- 目录操作:创建、删除、浏览、切换
- 批量操作:批量上传、批量下载(在增强部分)
- 文件信息:大小、修改时间
- 错误处理:完善的异常处理机制
使用这个类可以方便地进行各种FTP操作,具有良好的可扩展性和可维护性。