Clearstatcache: примеры (PHP)
clearstatcache(bool $clear_realpath_cache = false, string $filename = ""): voidФункция clearstatcache() очищает кеш состояния файлов, который PHP использует для ускорения выполнения операций с файловой системой. Эта функция применяется в случаях, когда информация о файле изменяется в процессе выполнения скрипта, и необходимо получить актуальные данные.
Функция имеет три необязательных параметра:
$clear_realpath_cache- булево значение, указывающее на необходимость очистки кеша реальных путей (по умолчанию false)$filename- строка с именем файла, для которого очищается кеш (применяется с PHP 5.3)
С PHP 5.3 можно очищать кеш только для конкретного файла, что улучшает производительность.
<?php
// Создание файла
file_put_contents('test.txt', 'начальное содержимое');
$size1 = filesize('test.txt');
// Изменение файла без очистки кеша
file_put_contents('test.txt', 'новое содержимое', FILE_APPEND);
$size2 = filesize('test.txt');
echo "Без clearstatcache: $size1 == $size2\n";
// Очистка кеша и повторная проверка
clearstatcache();
$size3 = filesize('test.txt');
echo "С clearstatcache: $size3\n";
?>Без clearstatcache: 30 == 30 С clearstatcache: 45
<?php
touch('file1.txt');
touch('file2.txt');
$time1 = filemtime('file1.txt');
$time2 = filemtime('file2.txt');
sleep(2);
touch('file1.txt');
clearstatcache(true, 'file1.txt');
$newTime1 = filemtime('file1.txt');
$newTime2 = filemtime('file2.txt');
echo "file1: $time1 -> $newTime1\n";
echo "file2: $time2 -> $newTime2\n";
?>file1: 1678901234 -> 1678901236 file2: 1678901234 -> 1678901234
В PHP существуют функции, которые также работают с файловой системой и могут требовать очистки кеша:
stat()- возвращает информацию о файлеlstat()- аналогична stat(), но для символьных ссылокfile_exists()- проверяет существование файла или каталогаis_file(),is_dir()- проверяют тип файлового объекта
Функция clearstatcache() очищает кеш для всех этих функций. Её использование обязательно при многократных обращениях к изменяющимся файлам.
<?php
// Ошибка: очистка кеша до изменения файла
$file = 'data.txt';
file_put_contents($file, 'первая запись');
$size1 = filesize($file);
clearstatcache(); // Преждевременная очистка
file_put_contents($file, 'вторая запись', FILE_APPEND);
$size2 = filesize($file); // Все равно устаревшие данные
echo "Size: $size1 -> $size2\n";
clearstatcache();
$size3 = filesize($file);
echo "Корректный размер: $size3\n";
?>Size: 24 -> 24 Корректный размер: 44
<?php
// Создание и удаление символической ссылки
symlink('/real/path/file.txt', 'link.txt');
$real1 = realpath('link.txt');
unlink('link.txt');
// Без очистки кеша реальных путей
clearstatcache();
$real2 = @realpath('link.txt');
echo "После удаления: $real2\n";
// С очисткой кеша реальных путей
clearstatcache(true);
$real3 = @realpath('link.txt');
echo "С очисткой кеша путей: $real3\n";
?>После удаления: /real/path/file.txt С очисткой кеша путей:
В PHP 8 функция clearstatcache() не претерпела значительных изменений по сравнению с PHP 7. Основные изменения произошли ранее:
- В PHP 5.3 добавлен параметр
$filenameдля выборочной очистки кеша - В PHP 5 добавлен параметр
$clear_realpath_cache - В PHP 8 улучшена производительность файловых операций в целом
<?php
class FileMonitor {
private $cache = [];
public function hasChanged($filename) {
$current = filemtime($filename);
clearstatcache(true, $filename);
if (!isset($this->cache[$filename])) {
$this->cache[$filename] = $current;
return false;
}
if ($this->cache[$filename] !== $current) {
$this->cache[$filename] = $current;
return true;
}
return false;
}
}
$monitor = new FileMonitor();
$file = 'log.txt';
file_put_contents($file, "Запись 1\n");
var_dump($monitor->hasChanged($file));
sleep(1);
file_put_contents($file, "Запись 2\n", FILE_APPEND);
var_dump($monitor->hasChanged($file));
?>bool(false) bool(true)
<?php
// Эффективная очистка кеша только для измененных файлов
$files = ['a.txt', 'b.txt', 'c.txt'];
$sizes = [];
foreach ($files as $file) {
touch($file);
$sizes[$file] = filesize($file);
}
// Изменение только одного файла
file_put_contents('b.txt', 'новое содержимое', FILE_APPEND);
// Очистка кеша только для измененного файла
clearstatcache(true, 'b.txt');
foreach ($files as $file) {
$newSize = filesize($file);
echo "$file: {$sizes[$file]} -> $newSize\n";
}
?>a.txt: 0 -> 0 b.txt: 0 -> 32 c.txt: 0 -> 0
<?php
// Создание файла и символической ссылки
file_put_contents('original.txt', 'данные');
symlink('original.txt', 'link.txt');
// Получение информации через ссылку
$linkSize = filesize('link.txt');
$linkReal = realpath('link.txt');
// Изменение оригинального файла
file_put_contents('original.txt', 'измененные данные');
// Очистка всего кеша
clearstatcache(true);
$newLinkSize = filesize('link.txt');
$newLinkReal = realpath('link.txt');
echo "Размер: $linkSize -> $newLinkSize\n";
echo "Реальный путь: $linkReal -> $newLinkReal\n";
?>Размер: 12 -> 32 Реальный путь: /path/original.txt -> /path/original.txt
Clearstatcache в Python
Python не имеет встроенного кеша состояния файлов, поэтому аналогичная функциональность не требуется. Каждый вызов файловых операций обращается к системе.
import os
import time
with open('test.txt', 'w') as f:
f.write('начало')
size1 = os.path.getsize('test.txt')
with open('test.txt', 'a') as f:
f.write('дополнение')
size2 = os.path.getsize('test.txt')
print(f"Размеры: {size1} -> {size2}")Размеры: 12 -> 24
Node.js также не кеширует состояние файлов по умолчанию, но имеет асинхронную модель работы.
const fs = require('fs');
fs.writeFileSync('test.txt', 'начало');
let stats1 = fs.statSync('test.txt');
fs.appendFileSync('test.txt', 'дополнение');
let stats2 = fs.statSync('test.txt');
console.log(`Размеры: ${stats1.size} -> ${stats2.size}`);Размеры: 12 -> 24