PHP 文件系统操作类

wen PHP项目 3

本文目录导读:

PHP 文件系统操作类

  1. 核心功能
  2. 高级功能
  3. 辅助功能
  4. 使用特点

我将为您创建一个完整的PHP文件系统操作类,包含常用的文件操作功能:

<?php
/**
 * 文件系统操作类
 * 提供常用的文件、目录操作功能
 */
class FileSystem {
    /** @var string 根目录路径 */
    private $rootPath;
    /** @var int 默认文件权限 */
    private $filePermission = 0755;
    /** @var int 默认目录权限 */
    private $dirPermission = 0755;
    /**
     * 构造函数
     * @param string $rootPath 根目录路径(可选)
     */
    public function __construct($rootPath = '') {
        $this->rootPath = $rootPath ? rtrim($rootPath, '/') . '/' : '';
    }
    /**
     * 设置根目录路径
     * @param string $path 路径
     * @return bool 是否设置成功
     */
    public function setRootPath($path) {
        if (is_dir($path)) {
            $this->rootPath = rtrim($path, '/') . '/';
            return true;
        }
        return false;
    }
    /**
     * 获取根目录路径
     * @return string 根目录路径
     */
    public function getRootPath() {
        return $this->rootPath;
    }
    /**
     * 获取完整的路径
     * @param string $path 相对路径
     * @return string 完整路径
     */
    private function getFullPath($path) {
        // 清理路径中的多余斜杠
        $path = str_replace(['/', '\\'], '/', $path);
        $path = preg_replace('/\/+/', '/', $path);
        return $this->rootPath . ltrim($path, '/');
    }
    /**
     * 创建目录(支持递归创建)
     * @param string $dir 目录路径
     * @param int $permission 权限
     * @return bool 是否成功
     */
    public function createDir($dir, $permission = null) {
        $fullPath = $this->getFullPath($dir);
        $perm = $permission ?: $this->dirPermission;
        if (is_dir($fullPath)) {
            return true;
        }
        // 尝试创建目录
        if (!mkdir($fullPath, $perm, true)) {
            // 如果失败,尝试逐个创建
            $dirs = explode('/', $fullPath);
            $path = '';
            foreach ($dirs as $dir) {
                $path .= $dir . '/';
                if (!is_dir($path) && !mkdir($path, $perm)) {
                    return false;
                }
                chmod($path, $perm);
            }
        }
        return is_dir($fullPath);
    }
    /**
     * 创建文件
     * @param string $file 文件路径
     * @param string $content 内容
     * @param bool $overwrite 是否覆盖
     * @return bool 是否成功
     */
    public function createFile($file, $content = '', $overwrite = false) {
        $fullPath = $this->getFullPath($file);
        // 检查文件是否存在
        if (file_exists($fullPath) && !$overwrite) {
            return false;
        }
        // 确保目录存在
        $dirName = dirname($fullPath);
        if (!is_dir($dirName)) {
            $this->createDir($dirName);
        }
        // 写入文件
        if (file_put_contents($fullPath, $content) !== false) {
            chmod($fullPath, $this->filePermission);
            return true;
        }
        return false;
    }
    /**
     * 写入文件内容
     * @param string $file 文件路径
     * @param string $content 内容
     * @param string $mode 写入模式(w-覆盖,a-追加)
     * @return bool 是否成功
     */
    public function writeFile($file, $content, $mode = 'w') {
        $fullPath = $this->getFullPath($file);
        // 确保目录存在
        $dirName = dirname($fullPath);
        if (!is_dir($dirName)) {
            $this->createDir($dirName);
        }
        $handle = fopen($fullPath, $mode);
        if ($handle) {
            fwrite($handle, $content);
            fclose($handle);
            return true;
        }
        return false;
    }
    /**
     * 读取文件内容
     * @param string $file 文件路径
     * @return string|bool 文件内容或false
     */
    public function readFile($file) {
        $fullPath = $this->getFullPath($file);
        if (!is_file($fullPath)) {
            return false;
        }
        return file_get_contents($fullPath);
    }
    /**
     * 读取文件内容(逐行读取)
     * @param string $file 文件路径
     * @return array|bool 文件行数组或false
     */
    public function readFileLines($file) {
        $fullPath = $this->getFullPath($file);
        if (!is_file($fullPath)) {
            return false;
        }
        return file($fullPath, FILE_IGNORE_NEW_LINES);
    }
    /**
     * 复制文件或目录
     * @param string $source 源路径
     * @param string $destination 目标路径
     * @return bool 是否成功
     */
    public function copy($source, $destination) {
        $sourcePath = $this->getFullPath($source);
        $destPath = $this->getFullPath($destination);
        if (is_file($sourcePath)) {
            // 复制文件
            if (!is_dir(dirname($destPath))) {
                $this->createDir(dirname($destPath));
            }
            return copy($sourcePath, $destPath);
        } elseif (is_dir($sourcePath)) {
            // 复制目录
            return $this->copyDir($sourcePath, $destPath);
        }
        return false;
    }
    /**
     * 复制目录(递归)
     * @param string $source 源目录
     * @param string $destination 目标目录
     * @return bool 是否成功
     */
    private function copyDir($source, $destination) {
        if (!is_dir($destination)) {
            $this->createDir($destination);
        }
        $items = scandir($source);
        foreach ($items as $item) {
            if ($item == '.' || $item == '..') {
                continue;
            }
            $src = $source . '/' . $item;
            $dest = $destination . '/' . $item;
            if (is_dir($src)) {
                $this->copyDir($src, $dest);
            } else {
                copy($src, $dest);
            }
        }
        return true;
    }
    /**
     * 移动文件或目录
     * @param string $source 源路径
     * @param string $destination 目标路径
     * @return bool 是否成功
     */
    public function move($source, $destination) {
        $sourcePath = $this->getFullPath($source);
        $destPath = $this->getFullPath($destination);
        // 确保目标目录存在
        if (!is_dir(dirname($destPath))) {
            $this->createDir(dirname($destPath));
        }
        return rename($sourcePath, $destPath);
    }
    /**
     * 删除文件
     * @param string $file 文件路径
     * @return bool 是否成功
     */
    public function deleteFile($file) {
        $fullPath = $this->getFullPath($file);
        if (is_file($fullPath)) {
            return unlink($fullPath);
        }
        return false;
    }
    /**
     * 删除目录(可选递归删除)
     * @param string $dir 目录路径
     * @param bool $recursive 是否递归删除
     * @return bool 是否成功
     */
    public function deleteDir($dir, $recursive = true) {
        $fullPath = $this->getFullPath($dir);
        if (!is_dir($fullPath)) {
            return false;
        }
        if ($recursive) {
            $items = scandir($fullPath);
            foreach ($items as $item) {
                if ($item == '.' || $item == '..') {
                    continue;
                }
                $path = $fullPath . '/' . $item;
                if (is_dir($path)) {
                    $this->deleteDir($path, true);
                } else {
                    unlink($path);
                }
            }
        }
        return rmdir($fullPath);
    }
    /**
     * 判断文件是否存在
     * @param string $file 文件路径
     * @return bool 是否存在
     */
    public function fileExists($file) {
        return is_file($this->getFullPath($file));
    }
    /**
     * 判断目录是否存在
     * @param string $dir 目录路径
     * @return bool 是否存在
     */
    public function dirExists($dir) {
        return is_dir($this->getFullPath($dir));
    }
    /**
     * 获取文件信息
     * @param string $file 文件路径
     * @return array|bool 文件信息数组或false
     */
    public function getFileInfo($file) {
        $fullPath = $this->getFullPath($file);
        if (!file_exists($fullPath)) {
            return false;
        }
        $info = stat($fullPath);
        return [
            'name' => basename($fullPath),
            'path' => $fullPath,
            'size' => $info['size'],
            'size_human' => $this->formatSize($info['size']),
            'type' => filetype($fullPath),
            'mime' => $this->getMimeType($fullPath),
            'extension' => pathinfo($fullPath, PATHINFO_EXTENSION),
            'permission' => substr(sprintf('%o', fileperms($fullPath)), -4),
            'owner' => $info['uid'],
            'group' => $info['gid'],
            'created' => date('Y-m-d H:i:s', $info['ctime']),
            'modified' => date('Y-m-d H:i:s', $info['mtime']),
            'accessed' => date('Y-m-d H:i:s', $info['atime']),
            'is_readable' => is_readable($fullPath),
            'is_writable' => is_writable($fullPath),
        ];
    }
    /**
     * 列出目录内容
     * @param string $dir 目录路径
     * @param bool $recursive 是否递归列出
     * @return array|bool 目录内容数组或false
     */
    public function listDir($dir = '', $recursive = false) {
        $fullPath = $this->getFullPath($dir);
        if (!is_dir($fullPath)) {
            return false;
        }
        $items = [];
        $entries = scandir($fullPath);
        foreach ($entries as $entry) {
            if ($entry == '.' || $entry == '..') {
                continue;
            }
            $path = $fullPath . '/' . $entry;
            $item = [
                'name' => $entry,
                'path' => $path,
                'type' => is_dir($path) ? 'dir' : 'file',
                'size' => is_file($path) ? filesize($path) : 0,
                'modified' => date('Y-m-d H:i:s', filemtime($path)),
            ];
            if ($recursive && is_dir($path)) {
                $item['children'] = $this->listDir($path, true);
            }
            $items[] = $item;
        }
        return $items;
    }
    /**
     * 搜索文件
     * @param string $pattern 模式(支持通配符)
     * @param string $dir 目录路径
     * @return array|bool 匹配的文件数组或false
     */
    public function search($pattern, $dir = '') {
        $fullPath = $this->getFullPath($dir);
        if (!is_dir($fullPath)) {
            return false;
        }
        $results = [];
        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($fullPath)
        );
        foreach ($iterator as $file) {
            if ($file->isFile() && fnmatch($pattern, $file->getFilename())) {
                $results[] = [
                    'path' => $file->getPathname(),
                    'name' => $file->getFilename(),
                    'size' => $file->getSize(),
                ];
            }
        }
        return $results;
    }
    /**
     * 获取文件大小
     * @param string $file 文件路径
     * @return int|bool 字节大小或false
     */
    public function fileSize($file) {
        $fullPath = $this->getFullPath($file);
        if (!is_file($fullPath)) {
            return false;
        }
        return filesize($fullPath);
    }
    /**
     * 格式化文件大小
     * @param int $bytes 字节数
     * @return string 格式化后的大小
     */
    public function formatSize($bytes) {
        if ($bytes >= 1073741824) {
            return number_format($bytes / 1073741824, 2) . ' GB';
        } elseif ($bytes >= 1048576) {
            return number_format($bytes / 1048576, 2) . ' MB';
        } elseif ($bytes >= 1024) {
            return number_format($bytes / 1024, 2) . ' KB';
        } else {
            return $bytes . ' B';
        }
    }
    /**
     * 获取文件MIME类型
     * @param string $file 文件路径
     * @return string MIME类型
     */
    public function getMimeType($file) {
        $fullPath = $this->getFullPath($file);
        if (!is_file($fullPath)) {
            return 'application/octet-stream';
        }
        $finfo = finfo_open(FILEINFO_MIME_TYPE);
        $mime = finfo_file($finfo, $fullPath);
        finfo_close($finfo);
        return $mime;
    }
    /**
     * 设置文件权限
     * @param string $file 文件路径
     * @param int $permission 权限值
     * @return bool 是否成功
     */
    public function setPermission($file, $permission) {
        $fullPath = $this->getFullPath($file);
        if (!file_exists($fullPath)) {
            return false;
        }
        return chmod($fullPath, $permission);
    }
    /**
     * 压缩文件或目录为ZIP
     * @param string $source 源路径
     * @param string $zipFile ZIP文件路径
     * @return bool 是否成功
     */
    public function zip($source, $zipFile) {
        $sourcePath = $this->getFullPath($source);
        $zipPath = $this->getFullPath($zipFile);
        if (!class_exists('ZipArchive')) {
            return false;
        }
        $zip = new ZipArchive();
        if ($zip->open($zipPath, ZipArchive::CREATE | ZipArchive::OVERWRITE) !== true) {
            return false;
        }
        if (is_dir($sourcePath)) {
            $this->addDirToZip($zip, $sourcePath, basename($sourcePath));
        } elseif (is_file($sourcePath)) {
            $zip->addFile($sourcePath, basename($sourcePath));
        } else {
            $zip->close();
            return false;
        }
        $zip->close();
        return file_exists($zipPath);
    }
    /**
     * 添加目录到ZIP(递归)
     * @param ZipArchive $zip ZIP对象
     * @param string $dir 目录路径
     * @param string $zipDir ZIP内目录名
     */
    private function addDirToZip($zip, $dir, $zipDir) {
        $items = scandir($dir);
        foreach ($items as $item) {
            if ($item == '.' || $item == '..') {
                continue;
            }
            $path = $dir . '/' . $item;
            $zipPath = $zipDir . '/' . $item;
            if (is_dir($path)) {
                $zip->addEmptyDir($zipPath);
                $this->addDirToZip($zip, $path, $zipPath);
            } elseif (is_file($path)) {
                $zip->addFile($path, $zipPath);
            }
        }
    }
    /**
     * 解压ZIP文件
     * @param string $zipFile ZIP文件路径
     * @param string $destDir 解压目录
     * @return bool 是否成功
     */
    public function unzip($zipFile, $destDir) {
        $zipPath = $this->getFullPath($zipFile);
        $destPath = $this->getFullPath($destDir);
        if (!class_exists('ZipArchive')) {
            return false;
        }
        if (!is_file($zipPath)) {
            return false;
        }
        $zip = new ZipArchive();
        if ($zip->open($zipPath) !== true) {
            return false;
        }
        $zip->extractTo($destPath);
        $zip->close();
        return true;
    }
    /**
     * 上传文件
     * @param array $file $_FILES中的文件数组
     * @param string $destDir 目标目录
     * @param array $options 选项(allowed_ext, max_size等)
     * @return array|bool 上传结果或false
     */
    public function upload($file, $destDir, $options = []) {
        if (!isset($file['error']) || $file['error'] !== UPLOAD_ERR_OK) {
            return false;
        }
        // 检查文件大小
        if (isset($options['max_size']) && $file['size'] > $options['max_size']) {
            return ['error' => '文件过大'];
        }
        // 检查文件类型
        $ext = strtolower(pathinfo($file['name'], PATHINFO_EXTENSION));
        if (isset($options['allowed_ext']) && !in_array($ext, $options['allowed_ext'])) {
            return ['error' => '文件类型不允许'];
        }
        // 生成文件名
        $newName = isset($options['new_name']) ? 
            $options['new_name'] . '.' . $ext : 
            uniqid() . '_' . $file['name'];
        // 确保目标目录存在
        $destPath = $this->getFullPath($destDir);
        if (!is_dir($destPath)) {
            $this->createDir($destPath);
        }
        $fullPath = $destPath . '/' . $newName;
        if (move_uploaded_file($file['tmp_name'], $fullPath)) {
            return [
                'success' => true,
                'path' => $fullPath,
                'name' => $newName,
                'size' => $file['size'],
            ];
        }
        return false;
    }
    /**
     * 获取目录总大小
     * @param string $dir 目录路径
     * @return int|false 字节大小或false
     */
    public function getDirSize($dir) {
        $fullPath = $this->getFullPath($dir);
        if (!is_dir($fullPath)) {
            return false;
        }
        $size = 0;
        $iterator = new RecursiveIteratorIterator(
            new RecursiveDirectoryIterator($fullPath)
        );
        foreach ($iterator as $file) {
            if ($file->isFile()) {
                $size += $file->getSize();
            }
        }
        return $size;
    }
    /**
     * 清理目录内所有内容
     * @param string $dir 目录路径
     * @return bool 是否成功
     */
    public function clearDir($dir) {
        $fullPath = $this->getFullPath($dir);
        if (!is_dir($fullPath)) {
            return false;
        }
        $items = scandir($fullPath);
        foreach ($items as $item) {
            if ($item == '.' || $item == '..') {
                continue;
            }
            $path = $fullPath . '/' . $item;
            if (is_dir($path)) {
                $this->deleteDir($path, true);
            } else {
                unlink($path);
            }
        }
        return true;
    }
    /**
     * 判断路径是否为绝对路径
     * @param string $path 路径
     * @return bool 是否绝对路径
     */
    public function isAbsolutePath($path) {
        if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN') {
            return preg_match('/^[A-Za-z]:[\\\\\/]/', $path) === 1;
        }
        return strpos($path, '/') === 0;
    }
    /**
     * 获取规范的路径
     * @param string $path 路径
     * @return string 规范化后的路径
     */
    public function normalizePath($path) {
        return preg_replace('/[\/\\\\]+/', '/', $path);
    }
}
// 使用示例
/*
$fs = new FileSystem('/var/www/html');
// 创建目录
$fs->createDir('uploads/images');
// 创建文件
$fs->createFile('temp/test.txt', 'Hello World');
// 读取文件
$content = $fs->readFile('temp/test.txt');
// 复制文件
$fs->copy('temp/test.txt', 'backup/test.txt');
// 移动文件
$fs->move('backup/test.txt', 'temp/moved.txt');
// 删除文件
$fs->deleteFile('temp/moved.txt');
// 列出目录
$items = $fs->listDir('uploads');
// 上传文件
if (isset($_FILES['file'])) {
    $result = $fs->upload($_FILES['file'], 'uploads', [
        'allowed_ext' => ['jpg', 'png', 'pdf'],
        'max_size' => 5 * 1024 * 1024  // 5MB
    ]);
}
// 压缩目录
$fs->zip('uploads', 'backup.zip');
// 获取文件信息
$info = $fs->getFileInfo('temp/test.txt');
echo $info['size_human'];  // 输出文件大小
*/

这个文件系统操作类包含了以下主要功能:

核心功能

  1. 目录操作:创建、删除、复制、移动、清空目录
  2. 文件操作:创建、读取、写入、复制、移动、删除文件
  3. 路径管理:支持相对路径和绝对路径,自动处理路径规范化

高级功能

  1. 文件上传:支持文件类型和大小限制
  2. 压缩解压:支持ZIP格式的压缩和解压
  3. 文件搜索:支持通配符模式搜索
  4. 目录统计:计算目录总大小

辅助功能

  1. 权限管理:设置文件权限
  2. MIME类型检测
  3. 文件大小格式化
  4. 文件信息获取(大小、类型、权限、修改时间等)

使用特点

  • 可以设置统一的根目录,简化路径管理
  • 所有操作都返回布尔值或详细信息,便于错误处理
  • 支持错误检查,不会产生意外错误
  • 代码注释详细,易于理解和扩展

可以根据实际需求对这个类进行扩展或修改。

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