You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

htaccess伪静态重写后如何获取PHP入口文件所在目录基础URL

问题原因

原有代码直接使用$_SERVER['REQUEST_URI']拼接路径,这个变量存储的是用户发起请求的完整URI,包含伪静态转发后的路径部分(比如测试场景里的/index.js),拼接后自然会出现路径重复的错误。

要兼容任意部署路径,核心是不要从请求URI反推部署路径,直接通过PHP内置的$_SERVER['SCRIPT_NAME']获取入口文件index.php的真实服务端路径,这个值不受重写规则影响,不管部署在根目录还是多少层子目录都能准确拿到入口位置。

修正方案
  1. 优化原有is_https()函数的判断逻辑,兼容Apache环境下HTTPS值为off的场景
  2. 新增基础URL获取函数,通过SCRIPT_NAME计算入口所在目录的URL,自动适配任意部署层级
  3. 调整路径拼接逻辑,直接在基础URL后拼接目标目录和q参数传递的路径,丢弃REQUEST_URI里的伪静态路径部分

修正后的完整代码如下:

function is_https() {
    // apache环境判断
    if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off') {
        return true;
    }
    // heroku等反向代理场景判断
    if (isset($_SERVER['HTTP_X_FORWARDED_PORT']) && isset($_SERVER['HTTP_X_FORWARDED_PROTO'])) {
        return $_SERVER['HTTP_X_FORWARDED_PORT'] == 443 || $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https';
    }
    return false;
}

function get_base_url() {
    $scheme = is_https() ? 'https' : 'http';
    $host = $_SERVER['HTTP_HOST'];
    // 获取入口文件index.php的服务端路径,不受重写规则影响
    $entryPath = $_SERVER['SCRIPT_NAME'];
    // 提取入口文件所在目录,统一处理末尾斜杠
    $basePath = rtrim(dirname($entryPath), '/');
    return "{$scheme}://{$host}{$basePath}/";
}

function main() {
    $addresses = json_decode(file_get_contents('ip.json'));
    $blocked = in_array($_SERVER['REMOTE_ADDR'], $addresses);
    $baseUrl = get_base_url();
    // 拼接目标路径,ltrim去掉q参数开头的斜杠避免双斜杠
    $url = $baseUrl . ($blocked ? 'block/' : 'game/') . ltrim($_GET['q'], '/');
    
    echo $url;
    // 如果只是读取本地文件,不需要走HTTP curl,直接用__DIR__拼接磁盘路径读取性能更好
    // 例:$filePath = __DIR__ . ($blocked ? '/block/' : '/game/') . ltrim($_GET['q'], '/');
}

if (isset($_GET['q'])) {
    main();
}
效果验证
  • 本地测试场景:访问http://localhost/~kuba/jcubic/support/order/app/index.js时,SCRIPT_NAME值为/~kuba/jcubic/support/order/app/index.php,计算得到的基础URL为http://localhost/~kuba/jcubic/support/order/app/,未封禁时生成的URL为http://localhost/~kuba/jcubic/support/order/app/game/index.js,符合预期。
  • 根目录部署场景:访问https://example.com/index.js时,SCRIPT_NAME值为/index.php,计算得到的基础URL为https://example.com/,未封禁时生成的URL为https://example.com/game/index.js,符合要求。

额外优化提示:如果只是需要读取服务器本地/game/、/block/目录下的文件,完全不需要构造HTTP URL走curl请求,直接用PHP常量__DIR__(也就是当前index.php所在的磁盘目录)拼接文件路径读取即可,性能更高,也不会受服务器环境、域名配置的影响。

内容的提问来源于stack exchange,提问作者jcubic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.30 03:48:25