is_link() 用于判断路径是否为符号链接,只检测链接文件本身存在性,不验证目标有效性;结合 readlink() 获取目标路径,用 lstat() 获取链接自身元数据,注意与 stat() 的区别。

用 is_link() 判断文件是否为符号链接
PHP 提供了原生函数 is_link(),专门用于检测路径是否指向一个符号链接(软链接)。它不关心目标是否存在,只看当前路径本身是不是链接文件。
常见错误是误用 file_exists() 或 is_file() —— 它们对有效符号链接会返回 true,但无法区分“普通文件”和“指向文件的链接”。
-
is_link('/path/to/symlink')→true(即使目标被删,只要链接文件本身存在) -
is_link('/path/to/real/file')→false -
is_link('/path/to/broken/link')→ 仍为true(链接文件没被删,只是目标失效)
结合 readlink() 获取目标路径
确认是符号链接后,常需读取它指向的真实路径,这时用 readlink()。注意它只接受字符串路径,不支持资源或句柄。
该函数返回相对或绝对路径字符串,也可能失败并触发警告(比如权限不足),建议配合 @ 抑制或提前检查可读性。
立即学习“PHP免费学习笔记(深入)”;
-
readlink('/var/www/html')可能返回../public - 若链接目标不可访问(如跨挂载点且无权限),
readlink()返回false - 要解析成绝对路径,可用
realpath(readlink($path)),但注意realpath()对断链会返回false
注意 lstat() 和 stat() 的关键区别
当需要获取符号链接自身的元数据(如创建时间、大小、inode),必须用 lstat();而 stat() 会自动跟随链接,返回目标文件的信息。
例如:lstat($path)['size'] 是链接文件本身的字节数(通常很小,几十字节),而 stat($path)['size'] 是目标文件的大小。
- 判断链接是否“自己被硬链接过”,可比对
lstat($path)['nlink']是否 >1 - 检查链接权限:用
lstat($path)['mode'] & 0777,不是fileperms()(后者也跟随链接) - 在容器或 NFS 环境中,
lstat()可能因底层不支持而返回不完整字段
实际场景中的典型误判点
开发中容易忽略符号链接的“双重身份”:它既是独立文件,又是跳转入口。比如用 copy() 复制一个符号链接,默认会复制目标内容而非链接本身;而 symlink() 创建的是新链接,不是硬链接。
- 备份脚本里直接
scandir()+is_file()会漏掉链接本身,应加is_link()分支处理 - Web 服务器配置允许符号链接(如 Apache 的
FollowSymLinks),但 PHP 脚本仍需自行校验路径合法性,防止目录穿越(如../../../etc/passwd) - 使用
glob('*.php')不会匹配符号链接(除非链接名以 .php 结尾且目标存在),因为它基于stat()行为











