如何通过PHP跨平台获取多站点统一父目录(无需指定子目录)
搞定多站点父目录定位的靠谱方案
我之前也踩过类似的路径定位坑,你的核心需求是不管代码在站点子目录的哪一层,都能自动揪出所有站点的父目录,之前的方法因为硬依赖站点目录名称替换,遇到特殊结构直接歇菜,那咱们换个更鲁棒的思路:
方案1:靠站点根目录的特征目录定位(强推!兼容Web/命令行)
从你之前的代码能看出来,每个站点根目录下都有configuration和functions这两个目录——这就是最好的“标识”!我们可以从当前脚本的路径开始往上爬,找到包含这两个目录的层级,那就是站点根目录,再取它的父目录就是你要的目标路径。
直接上代码:
// 先拿到当前脚本的绝对真实路径 $currentPath = realpath(__DIR__); $siteRoot = null; // 向上遍历目录,直到找到站点根或者摸到系统根目录(防止无限循环) while ($currentPath !== '/' && $currentPath !== dirname($currentPath)) { // 检查当前目录是不是站点根(有没有那两个特征目录) $configDir = $currentPath . DIRECTORY_SEPARATOR . 'configuration'; $funcDir = $currentPath . DIRECTORY_SEPARATOR . 'functions'; if (is_dir($configDir) && is_dir($funcDir)) { $siteRoot = $currentPath; break; } // 没找到就往上走一层 $currentPath = dirname($currentPath); } if ($siteRoot) { // 终于拿到所有站点的父目录啦! $commonParentPath = dirname($siteRoot) . DIRECTORY_SEPARATOR; // 重新定义你需要的路径变量 $CommonPath = $commonParentPath . 'common' . DIRECTORY_SEPARATOR; $ConfigPath = $siteRoot . DIRECTORY_SEPARATOR . 'configuration' . DIRECTORY_SEPARATOR; $FunctionsPath = $siteRoot . DIRECTORY_SEPARATOR . 'functions' . DIRECTORY_SEPARATOR; } else { // 处理找不到的情况,按需调整 trigger_error('找不到站点根目录!检查下你的目录结构哦', E_USER_ERROR); }
这个方案的好处:
- 完全不挑站点目录的名字,不管是
site1.loc还是啥奇怪的结构都能适配 - 不管代码在站点下的哪一层子目录,都能自动找到根
- Windows和Linux的路径分隔符自动适配,不用操心
- Web环境和命令行脚本都能用
方案2:用服务器的DOCUMENT_ROOT(仅Web环境可用)
如果你的代码只在Web服务器上跑,那可以直接用服务器给的DOCUMENT_ROOT变量,它直接指向站点根目录,再取父目录就完事了,代码更简洁:
// 先确认DOCUMENT_ROOT存在(CLI模式下没有这个变量) if (!empty($_SERVER['DOCUMENT_ROOT'])) { $siteRoot = realpath($_SERVER['DOCUMENT_ROOT']); $commonParentPath = dirname($siteRoot) . DIRECTORY_SEPARATOR; $CommonPath = $commonParentPath . 'common' . DIRECTORY_SEPARATOR; $ConfigPath = $siteRoot . DIRECTORY_SEPARATOR . 'configuration' . DIRECTORY_SEPARATOR; $FunctionsPath = $siteRoot . DIRECTORY_SEPARATOR . 'functions' . DIRECTORY_SEPARATOR; } else { trigger_error('DOCUMENT_ROOT不可用哦,这个方法只适合Web环境', E_USER_ERROR); }
为啥之前的代码会失效?
你之前的代码是把dirname(__DIR__)拆成路径片段,替换最后一段得到父目录,但如果代码所在的子目录超过一层(比如site1.loc/app/inc/script.php),dirname(__DIR__)拿到的是app目录,不是站点根site1.loc,这时候替换后路径直接就错了。新方案靠特征目录定位站点根,从根源上解决了这个问题。
内容的提问来源于stack exchange,提问作者user5175034
相关产品推荐
相关产品推荐

