void clearstatcache ([ bool $clear_realpath_cache = false [, string $filename ]] )
| 参数 | 描述 | 默认值 |
|---|---|---|
| clear_realpath_cache | 可选。是否清除真实路径缓存 | false |
| filename | 可选。指定要清除缓存的文件路径 仅在clear_realpath_cache为true时有效 |
- |
PHP会对某些文件系统函数的结果进行缓存,以提高性能。但在以下情况下,缓存可能会导致获取到过时的信息:
这时就需要使用 clearstatcache() 来清除缓存,获取最新的文件信息。
以下函数的结果会被PHP缓存,调用clearstatcache()可以清除这些函数的缓存:
stat()lstat()file_exists()is_writable()is_readable()is_executable()is_file()is_dir()is_link()filectime()fileatime()filemtime()fileinode()filegroup()fileowner()<?php
// 创建一个文件并写入内容
$filename = "test.txt";
file_put_contents($filename, "初始内容");
// 第一次获取文件大小
$size1 = filesize($filename);
echo "第一次文件大小: " . $size1 . " 字节\n";
// 追加内容到文件
file_put_contents($filename, "\n追加的内容", FILE_APPEND);
// 第二次获取文件大小(可能会获取缓存的值)
$size2 = filesize($filename);
echo "第二次文件大小(未清除缓存): " . $size2 . " 字节\n";
// 清除缓存
clearstatcache();
// 第三次获取文件大小
$size3 = filesize($filename);
echo "第三次文件大小(已清除缓存): " . $size3 . " 字节\n";
// 清理
unlink($filename);
?>
<?php
$filename = "example.php";
// 创建文件
touch($filename);
// 设置文件权限为只读
chmod($filename, 0444);
// 检查是否可写
$writable1 = is_writable($filename);
echo "第一次检查是否可写: " . ($writable1 ? '是' : '否') . "\n";
// 修改文件权限为可写
chmod($filename, 0644);
// 再次检查是否可写(可能会获取缓存的值)
$writable2 = is_writable($filename);
echo "第二次检查是否可写(未清除缓存): " . ($writable2 ? '是' : '否') . "\n";
// 清除缓存
clearstatcache();
// 第三次检查是否可写
$writable3 = is_writable($filename);
echo "第三次检查是否可写(已清除缓存): " . ($writable3 ? '是' : '否') . "\n";
// 清理
unlink($filename);
?>
<?php
$filename = "temp_file.txt";
// 检查文件是否存在
echo "文件创建前是否存在: " . (file_exists($filename) ? '是' : '否') . "\n";
// 创建文件
file_put_contents($filename, "测试内容");
// 检查文件是否存在(可能会获取缓存的值)
echo "文件创建后是否存在(未清除缓存): " . (file_exists($filename) ? '是' : '否') . "\n";
// 清除缓存
clearstatcache();
// 再次检查文件是否存在
echo "文件创建后是否存在(已清除缓存): " . (file_exists($filename) ? '是' : '否') . "\n";
// 删除文件
unlink($filename);
// 检查文件是否存在
echo "文件删除后是否存在(未清除缓存): " . (file_exists($filename) ? '是' : '否') . "\n";
// 清除缓存
clearstatcache();
// 再次检查文件是否存在
echo "文件删除后是否存在(已清除缓存): " . (file_exists($filename) ? '是' : '否') . "\n";
?>
<?php
// 创建一个符号链接
$target = "real_file.txt";
$link = "symlink.txt";
// 创建目标文件
file_put_contents($target, "真实文件内容");
// 创建符号链接
if (!file_exists($link)) {
symlink($target, $link);
}
// 获取真实路径
$realpath1 = realpath($link);
echo "第一次真实路径: " . $realpath1 . "\n";
// 删除并重新创建符号链接
unlink($link);
symlink($target, $link);
// 获取真实路径(可能会获取缓存的值)
$realpath2 = realpath($link);
echo "第二次真实路径(未清除缓存): " . $realpath2 . "\n";
// 清除真实路径缓存
clearstatcache(true, $link);
// 获取真实路径
$realpath3 = realpath($link);
echo "第三次真实路径(已清除缓存): " . $realpath3 . "\n";
// 清理
unlink($link);
unlink($target);
?>
<?php
/**
* 文件状态监控器类
*/
class FileStatusMonitor {
private $filename;
private $lastModified;
private $lastSize;
public function __construct($filename) {
$this->filename = $filename;
$this->updateStatus();
}
/**
* 更新文件状态(清除缓存并获取最新信息)
*/
private function updateStatus() {
clearstatcache();
if (file_exists($this->filename)) {
$this->lastModified = filemtime($this->filename);
$this->lastSize = filesize($this->filename);
} else {
$this->lastModified = null;
$this->lastSize = null;
}
}
/**
* 检查文件是否被修改
*/
public function isModified() {
$previousModified = $this->lastModified;
$previousSize = $this->lastSize;
$this->updateStatus();
if (!file_exists($this->filename)) {
return $previousModified !== null; // 文件被删除
}
return ($this->lastModified !== $previousModified) ||
($this->lastSize !== $previousSize);
}
/**
* 获取文件信息
*/
public function getFileInfo() {
$this->updateStatus();
if (!file_exists($this->filename)) {
return ['exists' => false];
}
clearstatcache();
return [
'exists' => true,
'size' => $this->lastSize,
'modified' => $this->lastModified,
'readable' => is_readable($this->filename),
'writable' => is_writable($this->filename),
'permissions' => decoct(fileperms($this->filename) & 0777),
'owner' => fileowner($this->filename)
];
}
}
// 使用示例
$monitor = new FileStatusMonitor("config.json");
// 模拟文件变化
file_put_contents("config.json", json_encode(['version' => '1.0']));
if ($monitor->isModified()) {
echo "文件已被修改\n";
$info = $monitor->getFileInfo();
print_r($info);
} else {
echo "文件未修改\n";
}
// 清理
unlink("config.json");
?>
<?php
/**
* 批量处理文件,正确处理缓存
*/
function processFiles($directory) {
if (!is_dir($directory)) {
return false;
}
$results = [];
$files = scandir($directory);
foreach ($files as $file) {
if ($file == '.' || $file == '..') {
continue;
}
$filepath = $directory . '/' . $file;
// 在处理每个文件前清除缓存
clearstatcache();
$info = [
'filename' => $file,
'path' => $filepath,
'exists' => file_exists($filepath),
'is_dir' => is_dir($filepath),
'is_file' => is_file($filepath),
'size' => filesize($filepath),
'modified' => filemtime($filepath),
'readable' => is_readable($filepath),
'writable' => is_writable($filepath)
];
$results[] = $info;
}
return $results;
}
/**
* 监控文件夹变化
*/
function monitorDirectoryChanges($directory, $interval = 1) {
$previousState = [];
while (true) {
// 清除缓存以确保获取最新状态
clearstatcache();
$currentState = [];
$files = scandir($directory);
foreach ($files as $file) {
if ($file == '.' || $file == '..') {
continue;
}
$filepath = $directory . '/' . $file;
clearstatcache(); // 为每个文件清除缓存
$currentState[$file] = [
'size' => filesize($filepath),
'modified' => filemtime($filepath)
];
}
// 检测变化
$changes = [];
foreach ($currentState as $file => $info) {
if (!isset($previousState[$file])) {
$changes[] = "新增文件: $file";
} elseif ($info['size'] != $previousState[$file]['size'] ||
$info['modified'] != $previousState[$file]['modified']) {
$changes[] = "文件修改: $file";
}
}
// 检测删除的文件
foreach ($previousState as $file => $info) {
if (!isset($currentState[$file])) {
$changes[] = "删除文件: $file";
}
}
if (!empty($changes)) {
echo date('Y-m-d H:i:s') . " 检测到变化:\n";
foreach ($changes as $change) {
echo " - $change\n";
}
}
$previousState = $currentState;
sleep($interval);
}
}
// 使用示例(注释掉以避免无限循环)
/*
$results = processFiles("/tmp");
print_r($results);
// monitorDirectoryChanges("/tmp"); // 这会无限循环,谨慎使用
*/
?>
// 不推荐:过度清除缓存
clearstatcache();
if (file_exists($file)) {
clearstatcache();
$size = filesize($file);
clearstatcache();
$modified = filemtime($file);
}
// 推荐:批量操作时一次性清除
clearstatcache();
$exists = file_exists($file);
$size = filesize($file);
$modified = filemtime($file);
// 当处理符号链接时,需要清除真实路径缓存
symlink('/original/path/file.txt', '/link/file.txt');
// 修改原文件位置后...
// 需要清除真实路径缓存以获取新的真实路径
clearstatcache(true, '/link/file.txt');
$realpath = realpath('/link/file.txt');