阅读前请先下载项目源码,边读边看源码以加深理解和实操,
源码地址已放于文章末尾!


第4篇:“万物皆可控”——玩转文件的增删改查
欢迎回来,我的“云盘掌控者”们!
到目前为止,我们的云盘已经像一个初具规模的“数字仓库”,有了坚固的“大门”(认证系统),也有了高效的“收货”(文件上传)和“盘点”(列表展示)流程。但是,一个只能进货和看货的仓库,离一个现代化的智能仓储中心还差得远呢!
真正的掌控,意味着对仓库里的每一件货物、每一个货架,都有绝对的处置权。今天,我们就来为用户赋予这份“上帝之手”,让他们可以随心所欲地整理自己的数字资产。我们将一次性解锁创建文件夹、重命名、移动和删除这四大核心管理权限!
核心探秘:PHP的文件系统“魔杖”
在PHP的世界里,操作服务器上的文件和文件夹,就像挥舞一根魔杖,简单而又强大。我们这次要用到的主要有以下几个“咒语”:
mkdir($path): “平地起高楼”。在指定的路径$path创建一个新目录。rename($old, $new): “偷天换日”。可以移动文件/文件夹,也可以在同一目录下进行重命名。堪称“指鹿为马”的神技。unlink($file): “灰飞烟灭”。删除一个文件。注意,它只对文件有效,删不了文件夹。rmdir($dir): “釜底抽薪”。删除一个空文件夹。是的,你没看错,必须是空的!RecursiveIteratorIterator: “斩草除根”。这是一个比较长的“咒语”,通常和RecursiveDirectoryIterator配合使用,能帮我们遍历一个文件夹下的所有子子孙孙,是实现“删除非空文件夹”这一终极奥义的关键。
明白了这些“咒语”,我们就可以开始动手改造我们的 index.php“总指挥”,让它学会处理这些新的指令了。
代码实战:“四位一体”逐个击破管理功能
所有的文件管理操作,其流程都惊人地相似:
- 前端发起指令:用户在
template.php界面上点击某个操作按钮。 - JavaScript 响应:JS捕获点击事件,弹出一个漂亮的模态框,让用户输入必要的信息(比如新文件夹名)。
- 表单提交:用户确认后,JS将指令和信息打包成一个表单,
POST给index.php。 - 后端执行:
index.php接收到指令,调用相应的PHP函数(就是我们上面说的那些“咒语”)完成操作。 - 刷新反馈:
index.php操作完成后,刷新页面,用户就能看到最新的结果。
接下来,我们一个一个来拆解。
1. 创建文件夹:“无中生有”的艺术
a. 文件路径定位: index.php (大约在 73行 附近)
b. 全面讲解引用:
$_POST['create_folder']: 我们在template.php的新建文件夹模态框表单里,会放一个name="create_folder"的提交按钮。isset()这个就代表用户执行了创建操作。$_POST['folder_name']: 用户在模态框里输入的新文件夹的名称。file_exists(): 在创建前,先检查一下同名文件夹是不是已经存在了,避免冲突。mkdir($path, 0777, true):$path: 要创建的完整路径。0777: 这是Linux系统中的文件权限代码,代表“读、写、执行”权限对所有用户开放。在开发环境中通常这么设置以避免权限问题。true: 这个参数非常重要!它代表允许递归创建。也就是说,如果你想创建a/b/c,而a和a/b都不存在,mkdir会自动帮你把它们都创建好。
c. 逐行注释与结构化分析:
// 文件路径: index.php
// 检查是否收到了“创建文件夹”的指令
if (isset($_POST['create_folder'])) {
// 从POST数据中获取用户想要创建的文件夹名称
$folderName = $_POST['folder_name'];
// 获取当前的路径,决定新文件夹在哪里创建
$currentPath = getCurrentPath();
// 拼接出新文件夹的完整物理路径
$newFolderPath = $currentPath . '/' . $folderName;
// 步骤1:检查该文件夹是否已存在
if (!file_exists($newFolderPath)) {
// 步骤2:如果不存在,则尝试创建
// @mkdir 前的 @ 符号用于抑制可能出现的警告信息,让我们的错误处理更统一
if (mkdir($newFolderPath, 0777, true)) {
$successMessage = '文件夹创建成功';
} else {
$errorMessage = '文件夹创建失败,请检查权限';
}
} else {
// 如果已存在,则设置错误消息
$errorMessage = '文件夹已存在';
}
}
d. 上下文关联:
当用户在 template.php 点击“新建文件夹”按钮,JS会弹出一个模态框。模态框里的表单提交后,就会触发 index.php 里的这段逻辑。执行完毕后,页面刷新,文件列表获取的逻辑会再次运行,新创建的文件夹就会出现在用户的视野里。整个过程行云流水。
2. 重命名:“指鹿为马”的神技
a. 文件路径定位: index.php (文件重命名约 167行,文件夹约 90行)
b. 全面讲解引用:
$_POST['rename_file']/$_POST['rename_folder']: 判断指令是重命名文件还是文件夹。$_POST['old_name']: 原始名称。$_POST['new_name']: 用户输入的新名称。rename($old, $new): 核心函数。当$old和$new在同一个目录下时,它的效果就是重命名。如果不在同一个目录,效果就是移动。
c. 逐行注释与结构化分析(以重命名文件为例):
// 文件路径: index.php
// 检查是否是“重命名文件”指令
if (isset($_POST['rename_file'])) {
$oldName = $_POST['old_name'];
$newName = $_POST['new_name'];
$currentPath = getCurrentPath();
// 拼接出旧文件和新文件的完整路径
$oldPath = $currentPath . '/' . $oldName;
$newPath = $currentPath . '/' . $newName;
// 步骤1:确保旧文件存在,且新文件名没有被占用
if (file_exists($oldPath) && !file_exists($newPath)) {
// 步骤2:执行重命名操作
if (rename($oldPath, $newPath)) {
$successMessage = '文件重命名成功';
} else {
$errorMessage = '文件重命名失败';
}
} else {
$errorMessage = '操作失败,可能源文件不存在或目标文件已存在';
}
}
d. 上下文关联:
逻辑和创建文件夹几乎一样。用户点击文件或文件夹旁边的“编辑”图标,JS弹出模态框,用户输入新名字后提交表单,触发这段逻辑。rename() 函数同时搞定了文件和文件夹的重命名,非常方便。
3. 删除文件:“灰飞烟灭”
a. 文件路径定位: index.php (大约在 187行 附近)
b. 全面讲解引用:
unlink($path): 删除文件的专用函数。简单直接,一步到位。
c. 逐行注释与结构化分析:
// 文件路径: index.php
// 检查是否是“删除文件”指令
if (isset($_POST['delete_file'])) {
$fileName = $_POST['file_name'];
$currentPath = getCurrentPath();
$filePath = $currentPath . '/' . $fileName;
// 步骤1:确认文件真的存在
if (file_exists($filePath)) {
// 步骤2:执行删除
if (unlink($filePath)) {
$successMessage = '文件删除成功';
} else {
$errorMessage = '文件删除失败';
}
} else {
$errorMessage = '文件不存在';
}
}
d. 上下文关联:
用户点击“删除”图标,JS弹出确认框(“你确定要删吗?删了可就没了!”),用户含泪点击“确定”后,表单提交,触发这段代码。unlink 执行,文件从硬盘上消失。
4. 删除文件夹:“斩草除根”的终极奥义
删除文件夹比删除文件要麻烦,因为它可能不是空的。我们需要自己实现一个递归删除。
a. 文件路径定位: index.php (大约在 110行 附近)
b. 全面讲解引用:
is_dir($path): 判断给定路径是否是一个目录。RecursiveDirectoryIterator($path): 创建一个可以递归遍历目录的迭代器。RecursiveIteratorIterator($iterator): 配合前者使用,可以深度优先或广度优先地“走”遍所有子目录和文件。CHILD_FIRST模式确保我们先处理完所有子文件/子目录,最后才处理父目录,这对于删除操作至关重要!$fileinfo->isDir(): 判断当前迭代项是文件还是目录。rmdir($path): 删除一个空目录。
c. 逐行注释与结构化分析:
// 文件路径: index.php
// 检查是否是“删除文件夹”指令
if (isset($_POST['delete_folder'])) {
$folderName = $_POST['folder_name'];
$currentPath = getCurrentPath();
$folderPath = $currentPath . '/' . $folderName;
// 步骤1:确认这是个文件夹
if (is_dir($folderPath)) {
// 步骤2:创建一个能“斩草除根”的迭代器
// 它会从最深层的子文件/子目录开始遍历
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($folderPath, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
// 步骤3:遍历所有子项并删除
foreach ($files as $fileinfo) {
// 如果是目录,就用 rmdir;如果是文件,就用 unlink
$todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
$todo($fileinfo->getRealPath());
}
// 步骤4:最后,删除已经变为空的顶层文件夹
if (rmdir($folderPath)) {
$successMessage = '文件夹删除成功';
} else {
$errorMessage = '文件夹删除失败';
}
} else {
$errorMessage = '文件夹不存在';
}
}
d. 上下文关联:
这段代码是整个管理功能中最复杂,但也最能体现编程之美的地方。它优雅地解决了“如何删除一个非空文件夹”的经典问题。通过 RecursiveIteratorIterator,我们确保在删除一个“收纳盒”(目录)之前,已经把它里面的所有“物品”(文件和子目录)都清理干净了,从而避免了 rmdir 只能删除空目录的限制。
总结与预告
太棒了!今天我们一口气解锁了云盘的四大核心管理能力。现在,用户不仅可以上传和查看文件,更可以像在自己电脑上一样,随心所欲地创建、重命名和删除文件及文件夹。我们的云盘,从一个“展示柜”正式进化成了一个强大的“文件管理工具”!
到现在,我们的云盘已经非常实用了。但是,作为一个追求极致体验的开发者,我们还能让它变得更酷!
在下一篇文章中,我们将聚焦于效率与体验的飞跃——“一键打包带走!”:批量操作与下载功能的实现。我们将学习如何让用户一次性选择多个文件,进行批量删除、批量移动,甚至是一键打包成ZIP下载!
准备好让你的云盘操作效率翻倍了吗?我们下期,不见不散!
911

被折叠的 条评论
为什么被折叠?



