stat
Returns an array of information about a file, including size, permissions and timestamps.
stat(string $filename): array|false- Added in PHP 4.0
Parameters
| Parameter | Type | Description |
|---|---|---|
$filename | string | Path to the file. If it is a symbolic link, stat() reports on the link's target. |
Return value
array|falseReturns an array with both numeric and string keys (dev, ino, mode, nlink, uid, gid, rdev, size, atime, mtime, ctime, blksize, blocks), or false on failure.
Errors
Emits an E_WARNING and returns false if the file cannot be stat'ed, for example when it does not exist or the path is unreadable.
Changelog
- PHP 7.4.0On Windows, dev is now the serial number of the volume containing the file and ino is the file identifier; both are 64-bit unsigned values and may overflow.
- PHP 7.4.0On Windows NTS builds, the size, atime, mtime and ctime of a symlink are now always those of the target, matching other platforms.
stat() performs one stat(2) system call and hands you everything the operating system knows about a file in a single array. The array is doubled up: index 7 and key size are the same value, so count() on it returns 26, not 13.
When to reach for it
- You need several attributes of one file and want a single syscall instead of
filesize()+filemtime()+fileperms(). - You want
inoanddevto tell whether two paths are hard links to the same file. - You need
ctime, the inode change time, which has no dedicated wrapper beyondfilectime().
What trips people up
PHP caches stat results per request. After you write to, chmod or delete a file, stat() may still report the old values until you call clearstatcache() — pass the filename as the second argument to clear just that entry.
Several fields are meaningless on Windows: uid and gid are always 0, and blksize and blocks are -1. mode mixes the file type bits with the permission bits, so mask it: $st['mode'] & 0777 for permissions, $st['mode'] & 0170000 for the type.
stat() follows symlinks. Use lstat() to describe the link itself, or fstat() when you already hold an open handle.
Example
When to use it
- Detect that two paths are hard links to the same file by comparing their dev and ino values.
- Show size, owner and last-modified time in a file-manager listing with one syscall per entry.
- Decide whether a cache file is stale by comparing its mtime against the source file's mtime.
Frequently asked questions
What is the difference between stat and lstat?
stat() follows symbolic links and describes the file they point at; lstat() describes the symlink itself. On a non-symlink path the two return identical data.
Why does count() on the stat array return 26?
Each of the 13 fields is stored twice, once under a numeric index and once under a name such as 'size'. Use array_slice($st, 13) or read the named keys directly if you need just one copy.
Does stat give the file creation time?
No. The ctime field is the inode change time — when permissions, ownership or link count last changed — not the creation time. Unix stat(2) does not expose a birth time to PHP.
More examples
Numeric and named keys are the same data
Every value appears twice, once under its numeric offset and once under its name. That is why count() returns 26 and why looping the array with foreach visits each field twice.
<?php
file_put_contents('demo.txt', str_repeat('a', 40));
$st = stat('demo.txt');
echo 'entries: ', count($st), "\n"; // 26, not 13
var_dump($st[7], $st['size']);
var_dump($st[9] === $st['mtime']);
unlink('demo.txt');Spotting a stale cached stat
The second stat() usually reports the original size of 3 because the result was cached. Only after clearstatcache() does the real size of 20 appear.
<?php
file_put_contents('demo.txt', 'one');
$a = stat('demo.txt');
file_put_contents('demo.txt', 'a much longer string');
$b = stat('demo.txt'); // still cached
echo $a['size'], ' -> ', $b['size'], "\n";
clearstatcache(true, 'demo.txt');
$c = stat('demo.txt');
echo 'after clear: ', $c['size'], "\n";
unlink('demo.txt');Reading the file type out of mode
Masking mode with 0170000 isolates the file-type bits: 0040000 marks a directory and 0100000 a regular file. Without the mask, mode also carries the permission bits.
<?php
mkdir('demo_dir');
file_put_contents('demo.txt', 'x');
foreach (['demo.txt', 'demo_dir'] as $p) {
$st = stat($p);
$type = ($st['mode'] & 0170000) === 0040000 ? 'dir' : 'file';
echo $p, ': ', $type, "\n";
}
unlink('demo.txt');
rmdir('demo_dir');
Discussion