lstat()
The lstat() function is a built-in PHP function that returns information about a symbolic link. This function takes a filename parameter that represents the
What is the lstat() Function?
lstat() gathers statistics (size, timestamps, owner, permissions, and more) about a file given by $filename. The "l" stands for link: unlike stat(), which follows a symbolic link and reports on the target it points to, lstat() reports on the link itself.
This distinction only matters for symbolic links. When $filename is an ordinary file, lstat() and stat() return identical data.
This page covers the syntax, the array it returns, a runnable example that contrasts it with stat(), and the common gotchas to watch for.
Syntax
lstat(string $filename): array|false$filename— path to the file or symbolic link to inspect.- Returns an associative array of statistics on success, or
falseon failure (for example, if the path does not exist).
A Runnable Example
The script below creates a real file and a symlink that points to it, then inspects both with lstat() and stat() so you can see the difference:
<?php
$target = sys_get_temp_dir() . '/lstat_target.txt';
$link = sys_get_temp_dir() . '/lstat_link';
file_put_contents($target, 'hello'); // 5-byte target file
@unlink($link);
symlink($target, $link);
$linkInfo = lstat($link); // the link itself
$targetInfo = stat($link); // follows the link to the target
echo "Link size (lstat): {$linkInfo['size']} bytes\n";
echo "Target size (stat): {$targetInfo['size']} bytes\n";
echo "Link modified: " . date('Y-m-d', $linkInfo['mtime']) . "\n";
unlink($link);
unlink($target);Typical output:
Link size (lstat): 65 bytes
Target size (stat): 5 bytes
Link modified: 2026-06-20The size from lstat() is the length of the symlink's path data, not the size of the file it points to — that is exactly the information stat() would hide from you.
The Returned Array
lstat() returns the same structure as stat(): a 26-element array where each value appears twice — once under a numeric index and once under a readable string key. Always prefer the named keys for clarity:
| Key | Meaning |
|---|---|
dev | Device number |
ino | Inode number |
mode | Inode protection mode (type + permissions) |
nlink | Number of hard links |
uid / gid | Owner user and group IDs |
rdev | Device type, if the inode is a device |
size | Size in bytes (for a link, the length of its path) |
atime | Last access time (Unix timestamp) |
mtime | Last modification time (Unix timestamp) |
ctime | Last inode-change time (Unix timestamp) |
blksize / blocks | Filesystem block size and number of blocks allocated |
Because the named and numeric keys hold the same values, $info['size'] and $info[7] are interchangeable — but the named form is far easier to read.
When to Use lstat() vs stat()
- Use
stat()when you care about the file's contents and want links transparently resolved. - Use
lstat()when you are auditing the filesystem itself — for example, distinguishing real files from symlinks, or detecting a dangling link whose target was deleted.
To test whether a path is a symlink before calling lstat(), pair it with is_link(). To read where a link points, use readlink(), and to create one, use symlink().
Gotchas
- Stale stat cache. PHP caches
stat/lstatresults per request. If a file changes during execution, callclearstatcache(true, $filename)before re-reading it. - Windows. Symbolic links exist on Windows but require elevated privileges to create; behavior can differ from POSIX systems.
- Permissions. Your PHP process needs read access to the directory containing the link. On hardened systems, security modules (such as SELinux or open_basedir restrictions) can block access even when file permissions look correct.
Conclusion
lstat() gives you the metadata of a symbolic link without following it — the one thing stat() cannot do. Reach for it whenever you need to inspect links themselves rather than their targets, read values by their named keys, and always check for a false return before trusting the result.