PHP操作FTP类怎么封装

wen PHP项目 1

本文目录导读:

PHP操作FTP类怎么封装

  1. 使用示例
  2. 增强功能补充

我来为您封装一个完整的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函数,并提供了更多的便捷方法,包括:

  1. 连接管理:连接、断开、状态检查
  2. 文件操作:上传、下载、删除、重命名
  3. 目录操作:创建、删除、浏览、切换
  4. 批量操作:批量上传、批量下载(在增强部分)
  5. 文件信息:大小、修改时间
  6. 错误处理:完善的异常处理机制

使用这个类可以方便地进行各种FTP操作,具有良好的可扩展性和可维护性。

抱歉,评论功能暂时关闭!