PHP functions filectime() fileatime() filemtime()

The PHP functions filectime() fileatime() filemtime() are very similar to each other. It's easy to get confused about when and which one to use - which function gets which timestamp. In this note, we will analyze what each function does - which timestamps are saved when creating a file, modifying, or reading files.

From the documentation

filectime( $file_path ) (create)

Returns the time of the last change to the specified file. Changes when created or modified.

This function checks for changes in the file's Inode and regular changes. Inode changes include changes in permissions, owner, group, and other metadata.

filemtime( $file_path ) (modified)
Returns the time of the last content modification of the file. Changes when the content of the file is modified.
fileatime( $file_path ) (access)

Returns the time of the last access to the file. Changes when the file is read (not always).

Note: On most servers, such updates to the file access time are disabled, as this function reduces the performance of applications that regularly access files.

Returns

Int/false. A number in Unix format or false on failure.

All functions cache the result. To clear the cache, use the function clearstatcache().

Cache example. If one of the "functions" is used first in a PHP process, and then the data or file content is changed (using touch(), file_put_contents()) and then the "functions" are used again, the functions will return the first result, although it has actually changed.

Examples

The result will depend on the server settings. On my server, the functions work as follows:

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

$__echo = function() use ($file){
	clearstatcache(); // clear the cache

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

We will get (without cache):

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

Based on the result, we can say:

Function Changes Does not change
chmod() ctime mtime, atime
file_put_contents() ctime and mtime atime
touch() ctime, mtime, atime -
file_get_contents() May change atime ctime, mtime

file_get_contents() does not change anything in this example because the change in atime is almost always disabled on the server for performance reasons.

We will get (with cache):

If we disable cache clearing (comment out clearstatcache()), we will get:

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