如何检查一个文件是否存在于PHP中

323 阅读4分钟

很多时候,你要么需要在PHP中移动文件,要么需要在文件中存储一些数据。在这两种情况下,事先知道一个文件是否存在可以帮助我们避免一些意外的行为。

PHP带有各种函数来处理与文件有关的不同类型的查询。在本教程中,我们将对所有这些函数做一个简单的概述,以便你可以选择一个最适合你情况的函数。

检查一个文件是否存在的重要性

在很多情况下,在做其他事情之前检查一个文件是否存在是很重要的。比方说,你的网站允许用户在你的服务器上上传图片文件,他们以后可以访问。可以假设,如果许多用户经常使用你的服务上传多个文件,他们总是有机会出现冲突的文件名。

在这种情况下,检查在你想保存用户最近上传的文件的位置是否已经有另一个文件变得很重要。然后,你可以选择采取一些措施,如将文件重命名为其他文件,或让用户知道他们的上传将覆盖现有文件。

让我们考虑另一种情况,在PHP中应该向一个文件追加数据。如果你为写所有数据而创建的文件由于某种原因被删除了,像这样的函数 file_put_contents()等函数会用指定的名字创建一个新的文件,并将数据存储在新创建的文件中。这在某些情况下可能是可取的,但并不总是这样的。因此,如果你在开始写数据之前已经期望文件存在,那么事先检查文件是否存在是有意义的。

检查一个文件是否存在于PHP中

有三个不同的函数可以用来检查一个文件在PHP中是否存在。

第一个函数是 file_exists().这个函数接受一个单一的参数,即你的文件所在的路径。请记住,它对现有的文件和目录都会返回真。这可能满足你的需要,也可能不满足。

你可以考虑使用 is_file()函数,如果你想确定你指定的路径是指向一个文件而不是一个目录。同样地,你可以使用 is_dir()函数来检查你指定的路径是否存在以及它是否指向一个目录。

<?php

$name = "squares.txt";
$directory = "squares.zip";

if(file_exists($name)) {
    echo 'The file "'.$name.'" exists.';
}

if(is_file($name)) {
    echo '"'.$name.'" is indeed a file.';
}

if(is_dir($directory)) {
    echo '"'.$directory.'" turned out to be a directory.';
}

?>

输出

The file "squares.txt" exists.
"squares.txt" is indeed a file.
"squares.zip" turned out to be a directory.

在上面的例子中,我故意将其中一个目录命名为squares.zip,以表明必须自己进行检查,而不是假设所提供的文件名实际上是一个文件名或一个目录。

重要的是要记住,is_file()is_dir() 都会返回false ,即使是实际存在的路径,当父目录没有正确的权限时也是如此。

检查文件是否存在,并且是可读或可写的

还有两个函数名为 is_readable()is_writable()的函数可以用来获取文件的一些额外信息,除了检查它是否存在。

顾名思义,is_readable() 函数将检查两件事。第一,文件或目录是否实际存在。第二,该文件是可读的。同样,is_writable() 函数也检查两件事,即文件或目录是否存在,是否可写。

<?php

$name = "squares.txt";

if(is_readable($name)) {
    echo 'We can read "'.$name.'".';
}

if(is_writable($name)) {
    echo 'We can also modify the contents of "'.$name.'".';
}

?>

输出

We can read "squares.txt". 
We can also modify the contents of "squares.txt".

我建议你在解释这两个函数的返回值时要小心。例如,当is_readable() 返回false时,我们的第一直觉是认为我们查询的文件是不可读的。然而,如果该文件不存在,该函数也会返回false。始终牢记这些函数的这个方面是很重要的。

小心缓存的结果

调用所有这五个函数,即file_exists(),is_file(),is_dir(),is_readable()is_writeable() ,所得到的返回值是被缓存的。这意味着重复调用一个函数,比方说is_file() ,可能会出现陈旧的结果。

PHP缓存了这些函数的结果,以提高性能。这就确保了多次调用同一文件的工作速度更快。然而,即使文件在脚本执行过程中发生变化,它们的返回值也会保持不变。

结果只对已经存在的文件进行缓存。这意味着调用一个函数is_file() ,对于不存在的文件会一直返回false ,但是一旦文件被创建,就开始返回true 。另一方面,对于第一次调用时已经存在的文件,该函数将一直返回true ,即使该文件已经被删除。

<?php

$name = "squares.txt";

if(is_file($name)) {
    echo '"'.$name.'" is indeed a file.';
}


// Manually delete the file while scripts waits.
sleep(5);

if(is_file($name)) {
    echo '"'.$name.'" is indeed a file.';
}

clearstatcache();

if(is_file($name)) {
    echo '"'.$name.'" is indeed a file.';
} else {
    echo 'The file probably no longer exists.';
}

?>

如果你对一个实际存在的文件运行上面的代码片段,然后在脚本等待时手动删除它,调用is_file() ,仍然会返回true 。然而,你可以通过简单地调用 clearstatcache()然后再查询该文件是否存在,就可以得到正确的结果。

输出

"squares.txt" is indeed a file.
"squares.txt" is indeed a file.
The file probably no longer exists.

还有一点需要记住的是,调用 unlink()的调用会自动清除缓存,这样你就可以在以后调用is_file() 等函数时得到新的结果。

最后的思考

在本教程的开始,我们学习了在PHP中检查文件存在的重要性。之后,我们了解了可以用来检查文件在PHP中是否存在的不同函数。我们还了解了其中一些函数可能具有的优点和缺点。

正如我在最后提到的,PHP会缓存其中一些函数调用的结果以提高性能。因此,在对这些文件做重要的事情之前,请确保清除缓存。