我想使用 PHP 删除文件。我已经使用了该unlink()
功能,但我想知道unlink
. 文件是否从服务器中完全删除?我想确保无法取回文件并且文件已从服务器中完全删除。
7 回答
以二进制模式打开文件进行写入,在整个文件上写入 1,关闭文件,然后取消链接。覆盖文件中的任何数据,使其无法恢复。
就我个人而言,我会说使用 1 而不是 0,因为 1 是实际数据并且总是会写入,而 0 可能不会写入,这取决于几个因素。
编辑:经过一番思考和阅读评论,我将采用混合方法,具体取决于您希望文件的“删除方式”,如果您只是希望使其无法恢复数据,请覆盖整个文件长度为 1,因为这很快,并破坏了数据,问题在于,它是否在磁盘上留下了一组统一数据长度,从而推断出一个文件 USED 在那里并给出文件长度,从而提供重要的取证信息。简单地写入随机数据也不会避免这种情况,好像这个文件周围的所有驱动器扇区都没有被触及,这也会留下取证痕迹。
考虑到取证删除、混淆和似是而非的否认的最佳解决方案(同样,这是矫枉过正,但我添加它是为了添加它),用 1 覆盖文件的整个长度,然后,对于文件的一半长度以字节为单位,从mt_rand
随机长度大小开始写入,从随机起点开始,给人的印象是许多不同长度的文件曾经位于该区域,从而创建了错误的踪迹。(同样,这完全是矫枉过正,通常只有连环杀手和中央情报局才需要,但我为了这样做而添加了它)。
美国政府过去建议对磁盘进行七步擦除。1) 所有'1' 2) 所有'0' 3) 模式'01' 4) 模式'10' 5) 随机模式6) 所有'1' 7) 随机模式,
重新查看代码示例,对于这种类型的擦除,使用 PHP 之类的语言是错误的,因为您在操作系统上的中继实际上是在擦除文件,而不是像上次擦除它或只是取消链接那样做一些切割器,但是......
(未经测试)
$filename = "/usr/local/something.txt";
$size = filesize($filename);
$pat1 = chr(0);
$pat2 = chr(255);
$pat3 = chr(170);
$pat4 = chr(85);
$mask = str_repeat($pat1, $size);
file_put_contents($filename, $mask);
$mask = str_repeat($pat2, $size);
file_put_contents($filename, $mask);
$mask = str_repeat($pat3, $size);
file_put_contents($filename, $mask);
$mask = str_repeat($pat4, $size);
file_put_contents($filename, $mask);
这可能无法回答如何完美删除“使用 PHP”的文件,但它回答了您的问题:“文件是否已从服务器中完全删除?”
在某些情况下,不!(在 UNIX/POSIX 操作系统上)。
根据官方 PHP unlink() 手册页上投票最高的评论,unlink 函数并没有真正删除文件,它是删除文件内容的系统链接!由于文件可以有多个文件名 (!) [符号链接?],只有在取消链接所有文件名时才会删除文件。因此,如果您的文件有 2 个名称,则 unlink() 不会真正删除该文件,除非您 unlink() 两个文件名。亲爱的 linux 人,如有必要,请在这里纠正我。
这可能就是为什么该函数被称为unLINK()而不是delete()!!!
这里是优秀评论的完整引用:
删除了一个大文件,但没有看到可用空间增加或磁盘使用量减少?使用 UNIX 或其他 POSIX 操作系统?unlink() 不是关于删除文件,而是关于删除文件名。手册页说:
`unlink - delete a name and possibly the file it refers to''. Most of the time a file has just one name -- removing it will also remove (free, deallocate) the
文件正文(有一个警告,见下文)。这是简单的,通常的情况。但是,一个文件在相同或不同的目录中具有多个名称(参见 link() 函数)是完全可以的。所有名称都将引用文件主体并keep it alive', so to say. Only when all the names are removed, the body of file actually is freed. The caveat: A file's body may *also* be
通过保持文件打开的进程保持活动状态(仍在使用磁盘空间)。只要进程保持打开状态,主体就不会被释放(不会释放磁盘空间)。事实上,有一种奇特的方法可以恢复被错误删除但仍被进程保持打开的文件......
看看这里unlink()
的姐妹功能。link()
通过 PHP 删除文件的 (imo) 最佳方法:
使用 PHP(在 linux 中)真正删除文件的方法是使用该exec()
函数,该函数执行真正的 bash 命令(用 linux bash 做事感觉是正确的顺便说一句)。在这种情况下,test.jpg
将通过执行以下操作删除文件:
exec("rm test.jpg);
有关如何rm
正确使用(删除)的更多信息,请参见此处。请注意:PHP需要删除文件的权限!
更新:不幸的是,rm
如果文件有两个名称/链接,linux 命令也不会真正删除文件。在这里查看更多信息。我将对此进行更深入的研究并提供反馈...
可能由于磁盘上的一些碎片,文件的某些部分会保留,即使文件被完全覆盖。
另一种方法是运行(通过shell_exec()
)外部程序,即系统特定的。这是一个示例(适用于 Windows),但我尚未对其进行测试。
这是 EFF 建议永久删除文件http://ssd.eff.org/tech/deletion的内容。
您应该进行多次覆盖以消除痕迹。例如使用美国 DoD 5220-22.M :“用一个字符覆盖所有可寻址位置,它的补码,然后是一个随机字符并验证”(来自 killdisk 站点)
在我的嵌入式 Ubuntu 设备中,我使用:echo exec('rm /usr/share/subdirectory/subdirectory/filename');
这对我有用。
如果你使用rm -f
(--force) 那么 linux 会
忽略不存在的文件和参数,从不提示
rm -d will
删除空目录
如果您rm --help
在提示符处输入,您将获得帮助屏幕。最后几行如下:
请注意,如果您使用 rm 删除文件,如果有足够的专业知识和/或时间,可能会恢复其中的一些内容。为了更好地确保内容确实不可恢复,请考虑使用 shred。
由于我的系统是一个“封闭”系统,所以我不担心违反安全问题。我的逻辑是必须有系统密码才能通过 SSH 进入操作系统,并且唯一的用户界面是通过网页。
@Sliq 的评论迄今为止仍然正确。你需要为你的情况做出决定。