2

问题背景

我有一个多媒体网络应用程序,用户可以在其中保存和删除文件。保存的文件用于各种应用程序范围的功能。

当文件被保存时,它们被放在目录树的深处(通常是 6 到 9 个文件夹深)。这些文件被放置在如此深的层次上,以确保管理员/超级用户在查看文件结构时很容易区分它们,与现有的手动系统相匹配。

例如,
“UploadedAssets”是根目录,可以包含以下文件夹结构:
\ith\sp\cookery\ckpe\interactives\timestep\blahblah\item1\image01.png
\ith\sp\cookery\ckpe\interactives\timestep\ blah_only\item1\image02.png
\ith\sp\cookery\ckpe\interactives\timestep\blah_only\item2\image03.png
\ith\sp\cookery\abcd\interactives\timestep\blahblah\item1\image66.png

  1. 前 5 个名称是用户可选择的(从动态下拉菜单中),每个名称大约有 20-25 个选项。
  2. 最后 3 个取决于任何用户输入(例如类别、标题等)。这是使用文本输入字段从用户那里收到的。这些可以是 1 个或最多 4 个目录。
  3. 最后一个目录“item1”可以有一个或多个文件没有子目录
  4. 每个目录除了最后一个(item1)可以有其他子目录
  5. 当我删除/删除文件时,显然程序知道文件位置的完整路径。

由于可能的目录名称选项的数量,即使在测试阶段,根“UploadedAssets”目录已经爆炸,并且有大量未使用的空目录和死分支。


我的问题是

一旦用户从目录中删除了一个/多个文件(例如item1中的image01.png),

  1. 如何从已删除的文件中向上遍历树(仅指向直接父节点)并删除父节点(如果父节点为空)。
  2. 删除时,如果其中一个目录有其他子/文件,则不要删除该目录并完成该过程。
  3. 在预定义的根目录处删除停止或
  4. 向上n级目录后停止

例如在上面给出的示例目录结构中,
如果用户删除image01.png那么它应该删除item1blahblah目录
如果用户删除image02.png那么它应该只删除它的父item1目录
如果用户删除image66.png那么它应该删除所有父目录包括abcd 的目录


我的尝试/研究

我知道如何使用 php 删除单个目录rmdir删除单个目录。但是无法考虑如何递归地使用它来解决我的问题。

我试图了解以下内容,但我不知道这些内容是否适合我的问题 PHP:取消链接目录中的所有文件,然后删除该目录

删除文件然后目录

http://php.net/manual/en/function.glob.php

https://stackoverflow.com/a/4490706/2337895

4

1 回答 1

0

因为这有一些开销,所以我建议您仅在绝对需要时从 PHP 执行此操作。您可以为此使用 Linuxfind命令:

find /path/to/dir -empty -type d -delete

我会把它放在一个 cron 工作中。如果您愿意,可以使用php 系统命令来执行此操作:

system('find /path/to/dir -empty -type d -delete', $retval);

使用它,您只需删除文件,然后让它仅每天运行一次左右,以检查并处理任何空目录。这可能看起来比用 PHP 编写的更骇人听闻,但它会运行得更快。它的可移植性较差,但对于大多数站点来说这并不重要。将此另存为rdel.bat(我始终确保您已打开资源管理器[Show hidden file extensions][2]文件夹选项,但如果您没有打开,请使用文本编辑器对话框中的下拉菜单Save As...以确保它具有正确的扩展名)。

更新:

要在 Windows 中执行相同的操作,请使用仅包含这一行的批处理文件:

for /f "delims=" %%d in ('dir /s /b /ad ^| sort /r') do rd "%%d"

通过切换到一个目录并运行您的新文件来测试它。它应该删除当前目录下的所有空目录。

要安排这个,只需在您的任务安排程序中添加一个条目。根据您使用的 Windows 版本,这会有所不同。确保正确设置工作目录(这是批处理文件知道从哪里开始的方式)。

这样做的问题是,在 Windows 中,很多垃圾文件是在空目录(即 Thumbs.db)中创建的。您可以通过在批处理文件中添加代码来删除这些文件中的任何一个来处理这个问题:

del /s /q Thumbs.db

将此添加到另一行上方,然后重复其他可能不需要的内容。

于 2014-03-20T04:57:34.147 回答