本文目录导读:

我将为您创建一个完整的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']; // 输出文件大小
*/
这个文件系统操作类包含了以下主要功能:
核心功能
- 目录操作:创建、删除、复制、移动、清空目录
- 文件操作:创建、读取、写入、复制、移动、删除文件
- 路径管理:支持相对路径和绝对路径,自动处理路径规范化
高级功能
- 文件上传:支持文件类型和大小限制
- 压缩解压:支持ZIP格式的压缩和解压
- 文件搜索:支持通配符模式搜索
- 目录统计:计算目录总大小
辅助功能
- 权限管理:设置文件权限
- MIME类型检测
- 文件大小格式化
- 文件信息获取(大小、类型、权限、修改时间等)
使用特点
- 可以设置统一的根目录,简化路径管理
- 所有操作都返回布尔值或详细信息,便于错误处理
- 支持错误检查,不会产生意外错误
- 代码注释详细,易于理解和扩展
可以根据实际需求对这个类进行扩展或修改。