PHP функции filectime() fileatime() filemtime()

Функции PHP filectime() fileatime() filemtime() очень похожи друг на друга. Легко запутаться, когда и какой нужно использовать - какая функция, какую метку времени получает. В этой заметке разберем что тут к чему - какие метки времени сохраняются при создании файла, какие при изменении или чтении файлов.

Из документации

filectime( $file_path ) (create)

Возвращает время последнего изменения указанного файла. Изменяется при создании, изменении файла.

Эта функция проверяет наличие изменений в Inode файла, и обычных изменений. Изменения Inode - это изменение разрешений, владельца, группы и других метаданных.

filemtime( $file_path ) (modified)
Возвращает время последнего изменения контента файла. Изменяется при изменении контента файла.
fileatime( $file_path ) (access)

Возвращает время последнего доступа к файлу. Изменяется при чтении файла (не всегда).

Заметка: на большинстве серверах такие обновления времени доступа к файлу отключены, так как эта функция снижает производительность приложений, регулярно обращающихся к файлам.

Возвращают

Int/false. Число в формате Unix или false при неудаче.

Все функции кэшируют результат. Чтобы сбросить кэш используйте функцию clearstatcache().

Пример кэша. Если в одном PHP процессе сначала использовать одну из «функции», а затем изменить данные или контент файла (использовать touch(), file_put_contents()) и попробовать снова использовать «функции», то функции вернут первый результат, хотя на самом деле он изменился.

Примеры

Результат будет зависеть от настроек сервера. На Бегете Функции работают так:

$file = FC_PARSER_PATH . 'info/_temp_test_file';
@ unlink( $file );
file_put_contents( $file, 'content' );

$__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 "\n\nchmod()\n";
chmod( $file, 0777 );
$__echo();

sleep(1);
echo "\n\nfile_get_contents()\n";
file_get_contents( $file );
$__echo();

sleep(1);
echo "\n\nfile_put_contents()\n";
file_put_contents( $file, 'content2' );
$__echo();

echo "\n\ntouch()\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
touch() ctime, mtime, atime -
file_get_contents() может менять atime ctime, mtime

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()