php include默认以执行该语句的脚本所在目录(即__dir__)为基准解析相对路径,而非浏览器访问路径或cli启动位置;需用__dir__拼接绝对路径、避免中文路径、确保目录x权限及iis中iusr账户权限。

路径解析不等于你认为的“当前目录”
PHP 的 include 不按浏览器访问路径、也不按 CLI 启动位置找文件,它默认以**执行该 include 语句的脚本所在目录(即 __DIR__)为基准**解析相对路径。比如你在 /var/www/html/admin/index.php 里写 include '../config.php',PHP 就真去 /var/www/html/config.php 找——哪怕你是从 /var/www/html/public/ 下通过 Apache 访问的这个 index.php。
最容易踩的坑是:在框架或路由入口统一加载时,include 'lib/helper.php' 看似合理,但实际执行它的文件可能在 /core/ 或 /app/ 下,导致上级目录层级算错。
实操建议:
- 在报错脚本开头加
echo __DIR__;,确认当前脚本物理位置 - 把所有相对路径改用
__DIR__ . '/relative/path.php'拼接,强制锚定 - 避免
./或../开头的写法,除非你 100% 控制调用链深度
Windows 下中文路径或编码不一致直接失败
Windows 默认用 GBK 编码读取文件系统元信息,而 PHP 文件多为 UTF-8 保存。如果 include 路径里含中文(比如 include '配置文件.php';),PHP 可能因编码转换失败而报 failed to open stream: No such file or directory,且不提示编码问题。
这不是文件不存在,是 PHP 根本没正确解码路径字符串。
实操建议:
- 彻底避免中文文件名和中文路径,全用英文+下划线
- 若必须支持,对路径做转码:
include iconv('UTF-8', 'GBK', __DIR__ . '/配置文件.php'); - 检查编辑器保存编码:VS Code / PHPStorm 默认 UTF-8 with BOM 可能引发隐式问题,选 “UTF-8 without BOM”
Linux 权限不止看文件,目录的 x 权限缺一不可
报错说“找不到文件”,但 ls -l 明明能看到。常见原因是父目录缺少 x(执行)权限——Linux 中,“进入目录” 和 “读取目录内容” 是两个权限。没有 x,PHP 进程连 /var/www/html/data/ 这个目录都进不去,自然找不到里面的 cache.json。
尤其在 Docker 或新部署环境,chmod 644 config.php 没用,得查整条路径:
- 运行
ls -ld /var/www/html/data,看权限字段末三位是否含x(如drwxr-xr-x✅,drw-r--r--❌) - 补权限:
chmod 755 /var/www/html/data(注意不是 644) - 确认 PHP 进程用户(如
www-data)能走通整条路径:sudo -u www-data ls -l /var/www/html/data/ - SELinux 启用时(CentOS/RHEL),
chmod无效,需chcon -t httpd_sys_rw_content_t /path/to/file
IIS + Windows 权限常被忽略的“来宾账户”
IIS 默认以 IUSR_XXX 账户运行 PHP,这个账户对新复制进来的文件**默认无任何权限**。即使文件在资源管理器里看起来“所有人都能读”,IIS 仍会报 failed to open stream。
错误典型表现:本地 WAMP 正常,一上 IIS 就崩;或者刚上传完文件就报错,过几分钟又好了(可能是手动点过属性→安全→继承权限)。
实操建议:
- 右键出问题的文件或目录 → 属性 → 安全 → 编辑 → 添加 → 高级 → 立即查找 → 输入
IUSR→ 选中IUSR_XXX→ 确定 - 勾选“读取”和“读取与执行”,不要只给“读取”
- 对整个网站根目录批量操作更稳妥,避免单个文件漏配
最麻烦的其实是组合场景:CLI 下跑得好好的脚本,放到 Web 服务器就报错,往往因为 getcwd() 和 __DIR__ 在不同 SAPI 模式下指向不同位置,而开发者只验证了一种环境。每次改路径,最好在 CLI、Apache、PHP-FPM 三种模式下各测一次。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











