如何获取PHP当前文件相对Web根目录而非系统根目录的路径
问题根源
你的旧代码逻辑从PHP设计上就不可能稳定返回timesheets/这类相对路径值:dirname(__FILE__)的原生作用就是返回当前文件所在的文件系统绝对路径,早年在Windows XAMPP、旧Linux服务器上能拿到相对路径,本质是PHP 5.3之前版本存在路径返回的兼容bug,加上旧环境的特殊配置做了路径重写,属于偶发的错误运行结果,不是代码逻辑本身正确。
你在新环境拿到/var/www/html/timesheets/这个值才是dirname(__FILE__)的正常返回结果,和doc_root、open_basedir配置无关——这两个参数都不会修改__FILE__常量的返回值,__FILE__永远返回当前执行文件的真实磁盘绝对路径,改这两个配置自然无效。
你出错的核心原因是混淆了两类完全不同的路径用途:
- 一类是PHP做本地文件读写(引入代码、读本地文件、存上传内容)用的文件系统路径,必须用磁盘绝对路径
- 另一类是拼URL、引用静态资源、做页面跳转用的Web访问路径,才需要相对Web服务根目录的路径值
你之前把文件系统路径直接当Web路径用,在旧环境靠bug刚好能跑,换到规范的新环境自然出错。
正确实现方案
不要修改文件系统路径的计算逻辑,把两类路径分开定义即可,代码放在应用根目录的入口文件里:
// 定义目录分隔符兼容写法(兼容你旧代码里的DIR_SEP习惯) defined('DIR_SEP') || define('DIR_SEP', DIRECTORY_SEPARATOR); // 文件系统应用根:所有本地文件读写、include/require操作全用这个值,不要改 define('APP_FS_ROOT', dirname(__FILE__) . DIR_SEP); // 计算Web访问根:所有拼URL、静态资源引用、跳转路径全用这个值 $docRoot = rtrim($_SERVER['DOCUMENT_ROOT'], '/\\'); $relativePath = substr(APP_FS_ROOT, strlen($docRoot)); // 统一转换为Unix风格的URL路径,兼容Windows/Linux服务器 define('APP_WEB_ROOT', '/' . trim(str_replace('\\', '/', $relativePath), '/') . '/');
适配效果
这套代码不需要修改任何服务器配置,在任意部署场景下都能返回正确值:
- 部署在Ubuntu的
/var/www/html/timesheets/,Web根为/var/www/html时,APP_WEB_ROOT返回/timesheets/ - 部署在旧XAMPP的
C:\xampp\htdocs\timesheets,Web根为C:\xampp\htdocs时,APP_WEB_ROOT返回/timesheets/ - 直接部署在Web根目录(比如
/var/www/html/)时,APP_WEB_ROOT返回/,不会出现多余的斜杠问题
注意事项
- 绝对不要为了拿相对路径修改
APP_FS_ROOT的值,本地文件操作必须用磁盘绝对路径,否则会出现相对路径解析错误、文件找不到的问题 - 静态资源引用、表单提交地址、页面跳转统一用
APP_WEB_ROOT拼接,比如引用CSS文件就写<link rel="stylesheet" href="<?= APP_WEB_ROOT ?>static/style.css">,无论应用装在几级子目录都能正常访问 - 如果你用的是PHP 5.3以上版本,也可以用
__DIR__代替dirname(__FILE__),两者效果完全一致。
内容的提问来源于stack exchange,提问作者Code83
相关产品推荐
相关产品推荐

