include路径默认相对当前工作目录(getcwd()),而非当前文件目录;以./或../开头时会忽略include_path并仅在getcwd()下查找,故推荐用__DIR__拼接绝对路径确保稳定。

路径写对了还报错,大概率不是路径本身的问题,而是 PHP 解析路径时根本没按你想的目录去查。
include 的路径到底是相对谁的?
很多人以为 include 'lib/utils.php' 是相对于当前文件(比如 admin/index.php)所在目录,其实不是。PHP 默认先查 getcwd()(当前工作目录),再查 __DIR__(当前文件所在目录)。这两者在 Web 和 CLI 下经常不一致:
- Web 请求(如 Nginx/Apache)下,
getcwd()通常是网站根目录(比如/var/www/html) - 命令行执行
php cli.php时,getcwd()是你运行命令的路径(比如/home/user/project),和cli.php所在位置可能完全不同 - 如果路径以
./或../开头,PHP 会跳过__DIR__,只在getcwd()下找 —— 这是很多“明明路径对却找不到”的根源
为什么用 __DIR__ 拼接最稳?
因为 __DIR__ 永远是当前 PHP 文件的绝对路径,不随执行方式、符号链接或工作目录变化而改变。它才是你真正能控制的锚点:
- 错误写法:
include '../config/db.php';→ 依赖getcwd(),跨环境极易失效 - 正确写法:
include __DIR__ . '/../config/db.php';→ 路径计算完全由当前文件位置决定 - 更安全的写法:
include dirname(__DIR__) . '/config/db.php';(dirname(__DIR__)等价于上一级目录) - 注意:
__DIR__末尾不含斜杠,拼接时要手动加/,否则变成/var/wwwconfig/db.php
include_path 被悄悄绕过了?
只要路径里出现 . 或 ..,哪怕只是开头带个 ./,PHP 就会直接忽略 include_path 配置,只在当前工作目录下找。这会导致两种典型现象:
访问全球海洋潮汐模型。功能包括查询指定日期、时间和地点的潮高、潮汐极值及格点天气数据。
立即学习“PHP免费学习笔记(深入)”;
- 你在
php.ini里加了include_path = ".:/var/www/lib",但include './lib/helper.php'依然报错 —— 因为./触发了绕过机制 - 用 Composer 自动加载时,某些框架封装的
include内部用了相对路径,结果把你的include_path完全废掉 - 验证方法:在报错前加一行
echo getcwd() . "\n" . __DIR__;,对比两者是否一致、是否真有你要的文件
符号链接和 realpath 的坑
当项目通过符号链接部署(比如 Web 根目录指向 /var/www/project/public,而 public 是个软链),__DIR__ 返回的是链接目标的真实路径,但 getcwd() 可能返回链接路径 —— 这会让两个路径彻底错开:
- 解决办法不是禁用软链,而是统一用
realpath(__DIR__)替代__DIR__,强制解析到真实物理路径 - 但注意:
realpath()对不存在的路径返回false,所以建议加判断:$path = realpath(__DIR__ . '/../config'); if ($path) include $path . '/db.php'; - 别滥用
realpath('./'):它返回的是getcwd()的真实路径,不是你想要的“当前文件所在目录”
最常被忽略的一点:路径问题往往在开发和生产环境表现不一致,不是代码错了,而是 getcwd() 在 Apache、Nginx、CLI、Docker 容器里默认行为不同。盯住 getcwd() 和 __DIR__ 的输出,比反复改路径有效得多。


















