Функции PHP: filectime(), fileatime(), filemtime()
Функции PHP filectime(), fileatime() и filemtime() очень схожи между собой. Часто можно запутаться, когда и какую из них использовать — какие временные метки они возвращают. В этой заметке мы разберём, что делает каждая функция и какие временные метки сохраняются при создании, изменении и чтении файлов.
ОДИН МОМЕНТ: ЧТО ЗНАЧИТ КАЖДАЯ ФУНКЦИЯ?
filectime($file_path)
Возвращает время последнего изменения указанного файла. Эта отметка обновляется, когда файл создаётся или изменяется. Функция проверяет изменения в inode файла (это информация о файле в файловой системе) и обычные изменения. К изменениям в inode относятся изменения прав доступа, владельца и другие метаданные.
filemtime($file_path)
Возвращает время последнего изменения содержимого файла. Эта отметка обновляется, только если изменяется сам текст или данные в файле.
fileatime($file_path)
Возвращает время последнего доступа к файлу. Эта отметка обновляется, когда файл читается, но не всегда.
Замечание: На большинстве серверов обновление времени доступа к файлу отключено, так как это снижает производительность приложений, которые часто обращаются к файлам.
РЕЗУЛЬТАТ ФУНКЦИЙ
Все три функции возвращают число в Unix-формате или false в случае ошибки. Также стоит отметить, что все функции кэшируют свои результаты. Чтобы очистить кэш, используйте функцию clearstatcache().
Пример кэширования
Если одна из функций вызывается первой в процессе PHP, а затем происходит изменение данных или содержимого файла (например, с помощью touch() или file_put_contents()), и затем функции вызываются снова, они вернут первое значение, хотя на самом деле данные изменились.
ПРИМЕР ИСПОЛЬЗОВАНИЯ
Рассмотрим следующий пример, который показывает использование всех трёх функций:
$file = '/путь/к/вашему/файлу/temp_test_file';
@unlink($file); // Удаляем файл, если он существует
file_put_contents($file, 'содержимое'); // Создаём новый файл с содержимым
$__echo = function() use ($file) {
clearstatcache(); // Очищаем кэш
echo time() . "t time()n";
echo filectime($file) . "t filectime()n";
echo filemtime($file) . "t filemtime()n";
echo fileatime($file) . "t fileatime()n";
};
$__echo(); // Первоначальный вызов функции
sleep(1); // Ждём секунду
echo "nnchmod()n"; // Изменяем права файла
chmod($file, 0777);
$__echo(); // Снова вызываем функции
sleep(1);
echo "nnfile_get_contents()n"; // Читаем содержимое файла
file_get_contents($file);
$__echo(); // Проверяем снова
sleep(1);
echo "nnfile_put_contents()n"; // Изменяем содержимое файла
file_put_contents($file, 'содержимое2');
$__echo();
echo "nntouch()n"; // Изменяем временные метки
touch($file, 22222222222, 33333333333);
touch($file, 44444444444, 55555555555);
$__echo();
ОЖИДАЕМЫЕ РЕЗУЛЬТАТЫ БЕЗ КЭША
1540437788 time()
1540437788 filectime()
1540437788 filemtime()
1540437788 fileatime()
chmod()
1540437789 time()
1540437789 filectime()
1540437788 filemtime()
1540437788 fileatime()
file_get_contents()
1540437790 time()
1540437789 filectime()
1540437788 filemtime()
1540437788 fileatime()
file_put_contents()
1540437791 time()
1540437791 filectime()
1540437791 filemtime()
1540437788 fileatime()
touch()
1540437791 time()
1540437791 filectime()
44444444444 filemtime()
55555555555 fileatime()
На основе результатов можно заметить следующее:
- Функция
chmod()изменяет толькоctime, не влияет наmtimeиatime. - Функция
file_put_contents()меняет какctime, так иmtime, но может не изменятьatime. - Функция
file_get_contents()обычно не изменяет ничего, так как изменениеatimeпочти всегда отключено на сервере для повышения производительности.
ОЖИДАЕМЫЕ РЕЗУЛЬТАТЫ С КЭШЕМ
Если не очищать кэш (например, закомментировав clearstatcache()), то получим:
1540437873 time()
1540437873 filectime()
1540437873 filemtime()
1540437873 fileatime()
chmod()
1540437874 time()
1540437873 filectime()
1540437873 filemtime()
1540437873 fileatime()
file_get_contents()
1540437875 time()
1540437873 filectime()
1540437873 filemtime()
1540437873 fileatime()
file_put_contents()
1540437876 time()
1540437873 filectime()
1540437873 filemtime()
1540437873 fileatime()
touch()
1540437876 time()
1540437873 filectime()
1540437873 filemtime()
1540437873 fileatime()
Как видно, при использовании кэша все функции продолжают возвращать одно и то же значение, несмотря на изменения в файле.
ЗАКЛЮЧЕНИЕ
Понимание различий между filectime(), fileatime() и filemtime() поможет вам корректно отслеживать изменения файлов в ваших проектах. Используйте их правильно, учитывая особенности работы с кэшем, чтобы избежать путаницы в результатах.