fileatime

Returns the Unix timestamp of when a file was last read or accessed.

Signature
fileatime(string $filename): int|false
  • Added in PHP 4.0.0

Parameters

ParameterTypeDescription
$filenamestringPath to the file.

Return value

int|falseThe last access time as a Unix timestamp, or false on failure.

Errors

Emits an E_WARNING and returns false if the stat call fails, for example when the file does not exist or the path is not readable.

fileatime reports the access time — the moment the file's data was last read, as recorded by the filesystem. It returns a raw Unix timestamp, so pass it to date() to get something human-readable.

When to reach for it

  • Cleaning up a cache directory by deleting entries nothing has read for N days.
  • Auditing which uploaded files have actually been downloaded.
  • Finding stale session or temp files.

What trips people up

Access times are far less reliable than modification times. Most modern Linux systems mount filesystems with relatime or noatime, which means atime is only updated once a day — or never. On such a mount fileatime effectively mirrors filemtime, and any logic that assumes "this file was read recently" will silently be wrong.

The other trap is PHP's stat cache. Within a single request PHP remembers the first stat result for a path, so calling fileatime again after something touched the file returns the old value. Call clearstatcache() — or clearstatcache(true, $filename) for one path — before re-reading.

Note that fileatime itself does not update the atime; opening and reading the file does.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Purge cached thumbnails that have not been served in the last 30 days.
  • Report which log archives are still being read by downstream tooling.
  • Detect temp files that were created but never consumed.

Frequently asked questions

What is the difference between fileatime, filemtime and filectime?

`fileatime` is when the file was last read, `filemtime` is when its contents last changed, and `filectime` is when its inode metadata (permissions, owner, link count) last changed. Only `filemtime` is reliable across all common filesystem mount options.

Why does fileatime keep returning the same value?

Either the filesystem is mounted `noatime`/`relatime` so reads do not update it, or PHP's stat cache is serving you a value from earlier in the same request. Call `clearstatcache()` to rule out the second cause.

How do I convert the fileatime result to a readable date?

Pass it to `date()`, for example `date('Y-m-d H:i:s', fileatime($path))`. The return value is a plain Unix timestamp in seconds.

More examples

Age of a file in days

A file just created has an age of 0 days, so the staleness check prints `false`. This subtraction against `time()` is the whole basis of an atime-driven cache eviction pass.

Example · php
<?php
file_put_contents('cache-entry.bin', str_repeat('x', 64));
clearstatcache();

$ageSeconds = time() - fileatime('cache-entry.bin');
$ageDays    = (int) floor($ageSeconds / 86400);

echo "age in days: $ageDays\n";
echo "older than 30 days: ", var_export($ageDays > 30, true), "\n";

unlink('cache-entry.bin');

Missing files return false, not zero

`var_dump` shows `bool(false)`. Casting that to int gives 0, which `date()` happily renders as 1 January 1970 — check `file_exists()` first rather than formatting a failure.

Example · php
<?php
$result = @fileatime('this-file-does-not-exist.txt');

var_dump($result);
echo "treat as epoch? ", ((int) $result === 0 ? 'yes, and that is the bug' : 'no'), "\n";

// The safe pattern
if (file_exists('this-file-does-not-exist.txt')) {
    echo date('c', fileatime('this-file-does-not-exist.txt'));
} else {
    echo "file missing, skipped\n";
}

The stat cache hides changes

Both lines print `true`: without `clearstatcache()` PHP returns the value it stat'ed earlier in the request, and only after clearing does it see the hour-later timestamp that `touch()` set.

Example · php
<?php
file_put_contents('cached.txt', 'v1');
$first = fileatime('cached.txt');

touch('cached.txt', time() + 3600);   // move times an hour into the future

$stale = fileatime('cached.txt');     // still the cached value
clearstatcache(true, 'cached.txt');
$fresh = fileatime('cached.txt');

echo "stale equals first: ", var_export($stale === $first, true), "\n";
echo "fresh is later:     ", var_export($fresh > $first, true), "\n";

unlink('cached.txt');

Discussion

  • Be the first to comment on this lesson.