PHP Conference Japan 2024

clearstatcache

(PHP 4, PHP 5, PHP 7, PHP 8)

clearstatcache清除文件状态缓存

描述

clearstatcache(bool $clear_realpath_cache = false, string $filename = ""): void

当您使用 stat()lstat() 或受影响函数列表(如下)中列出的任何其他函数时,PHP 会缓存这些函数返回的信息以提供更快的性能。但是,在某些情况下,您可能希望清除缓存的信息。例如,如果在单个脚本中多次检查同一个文件,并且该文件在脚本运行期间有被删除或更改的风险,您可以选择清除状态缓存。在这种情况下,您可以使用 clearstatcache() 函数清除 PHP 缓存的文件信息。

您还应该注意,PHP 不会缓存关于不存在的文件的信息。因此,如果您对不存在的文件调用 file_exists(),它将返回 false,直到您创建该文件。如果您创建了该文件,即使您随后删除该文件,它也会返回 true。但是,unlink() 会自动清除缓存。

注意:

此函数缓存有关特定文件名的信息,因此只有当您对同一个文件名执行多个操作并需要该特定文件的有关信息不被缓存时,才需要调用 clearstatcache()

受影响的函数包括 stat()lstat()file_exists()is_writable()is_readable()is_executable()is_file()is_dir()is_link()filectime()fileatime()filemtime()fileinode()filegroup()fileowner()filesize()filetype()fileperms()

参数

clear_realpath_cache

是否也清除 realpath 缓存。

filename

仅清除特定文件名的 realpath 缓存;仅当 clear_realpath_cachetrue 时使用。

返回值

不返回任何值。

示例

示例 #1 clearstatcache() 示例

<?php
$file
= 'output_log.txt';

function
get_owner($file)
{
$stat = stat($file);
$user = posix_getpwuid($stat['uid']);
return
$user['name'];
}

$format = "UID @ %s: %s\n";

printf($format, date('r'), get_owner($file));

chown($file, 'ross');
printf($format, date('r'), get_owner($file));

clearstatcache();
printf($format, date('r'), get_owner($file));
?>

以上示例将输出类似于以下内容

UID @ Sun, 12 Oct 2008 20:48:28 +0100: root
UID @ Sun, 12 Oct 2008 20:48:28 +0100: root
UID @ Sun, 12 Oct 2008 20:48:28 +0100: ross

添加注释

用户贡献的注释 6 条注释

matt_m at me dot com
13 年前
如果您对远程文件执行 file_exists(),例如:

<?php
if (file_exists("ftp://ftp.example.com/somefile"))
?>

则 unlink() 不会清除缓存。

在这种情况下,即使您成功调用了 unlink(),也必须调用 clearstatcache()。
然后 file_exists() 将正确返回 false。
msaladna at apisnetworks dot com
4 年前
clearstatcache() 不会规范化路径。clearstatcache(true, "/a/b/c") 与 clearstatcache(true, "/a/b//c") 不同。
vechenjivot at gmail dot com
4 年前
虽然未在文档中说明,但似乎 clearstatcache() 只清除其被调用的进程的缓存。我有两个 PHP 脚本同时运行,第一个脚本调用了 clearstatcache(),但第二个脚本仍然会死锁,除非我也在其中调用 clearstatcache()。

脚本 1
<?php
touch
('system.lock');
...
unlink('system.lock');
clearstatcache(); // unlink应该已经完成此操作?
?>

脚本 2
<?php
while (is_file('system.lock') {
sleep(1);
clearstatcache(); // 没有这个,脚本 2 将永远死锁!
}
?>

我还发现了这个页面,它得出了相同的结论
https://stackoverflow.com/questions/9251237/clearstatcache-include-path-sessions
David Spector
5 年前
注意,此函数仅影响文件元数据。但是,所有 PHP 文件系统函数也会自行缓存实际的文件内容。如果需要,您可以在 PHP.ini 中使用“realpath_cache_size = 0”指令来禁用内容缓存。默认内容缓存超时时间为 120 秒。

在开发工作和某些类型的应用程序中,内容缓存不是一个好主意,因为您的代码可能会读取刚刚更改的文件的旧数据。

注意:这与浏览器通常对所有 GET 请求(大部分 Web 访问)执行的缓存是分开的(除非 HTTP 标头覆盖它)。它也与可选的 Apache 服务器缓存分开。
bj at wjblack dot com
9年前
为了更清晰地说明这一点(并方便搜索引擎查找)

如果在PHP之外进行任何类型的文件操作(例如通过system()调用),则可能需要在对文件/目录/任何内容进行任何进一步测试之前清除状态缓存。例如

<?php
// is_dir() 强制执行状态调用,因此缓存已填充
if( is_dir($foo) ) {
system("rm -rf " . escapeshellarg($foo));
if(
is_dir($foo) ) {
// ...仍然为真,即使rm成功,因为它只是
// 读取缓存,而不是重新运行stat()
}
}
?>

在system调用后添加clearstatcache(),一切都会很好(除了由于清除状态缓存而导致的少量性能下降:-()。
Gabriel
5 年前
$filename 参数的定义让你认为它只期望文件名,但如果你也提供路径+文件名,它也能工作。

这方面应该更清晰。
To Top