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

如何通过.htaccess重写URL,让PHP的$_SERVER['REQUEST_URI']获取重写后地址?

解决.htaccess重写后PHP无法获取重写URI的问题

我之前也碰到过类似的场景,要让重写后的URL能被PHP的$_SERVER['REQUEST_URI']捕获,同时让Flight PHP路由正确处理epub/mobi文件的下载请求,得从**.htaccess规则配置和Flight路由适配**两方面入手,下面是具体的解决方案:

一、编写正确的.htaccess重写规则

首先要确保规则会检查文件是否存在(符合你的需求),并且重写后能把必要的信息传递给Flight,同时让PHP能拿到重写后的路径。

RewriteEngine On

# 仅当请求的是真实存在的epub/mobi文件时才触发重写
RewriteCond %{REQUEST_FILENAME} -f
RewriteCond %{REQUEST_URI} \.(epub|mobi)$ [NC]
# 重写到Flight的下载路由,同时传递原始文件名作为查询参数(方便统计具体书籍)
# QSA参数会保留原始请求的查询字符串,L表示这是最后一条匹配规则
RewriteRule ^(.+)\.(epub|mobi)$ /download/$2?file=$1.$2 [L,QSA]

规则解释:

  • %{REQUEST_FILENAME} -f:验证请求的文件确实存在于服务器上
  • \.(epub|mobi)$ [NC]:匹配以epub或mobi结尾的请求,NC表示不区分大小写
  • RewriteRule中的$2对应文件后缀(epub/mobi),$1对应文件名,最终重写到/download/[后缀]路径

二、配置Flight PHP适配重写后的URI

默认情况下,$_SERVER['REQUEST_URI']可能会保留原始的请求地址(比如/book.epub),而我们需要让Flight识别重写后的/download/epub路径。可以通过以下方式调整:

在你的Flight入口文件(比如index.php)中添加:

// 优先使用重写后的REDIRECT_URL,如果不存在则 fallback 到REQUEST_URI
Flight::set('flight.request.url', $_SERVER['REDIRECT_URL'] ?? $_SERVER['REQUEST_URI']);

// 定义对应的下载路由
Flight::route('GET /download/@format', function($format) {
    // 获取传递的原始文件名
    $targetFile = $_GET['file'] ?? '';
    
    // 这里添加你的下载次数统计逻辑
    // 比如:更新数据库中对应书籍的下载计数
    // countDownloads($targetFile);

    // 验证文件存在后,返回给用户下载
    $filePath = __DIR__ . '/' . $targetFile;
    if (file_exists($filePath) && is_readable($filePath)) {
        // 设置正确的Content-Type
        $mimeType = $format === 'epub' ? 'application/epub+zip' : 'application/x-mobipocket-ebook';
        header('Content-Type: ' . $mimeType);
        header('Content-Disposition: attachment; filename="' . basename($filePath) . '"');
        header('Content-Length: ' . filesize($filePath));
        
        readfile($filePath);
        exit;
    } else {
        // 文件不存在时返回404
        Flight::notFound();
    }
});

Flight::start();

关键说明:

  • $_SERVER['REDIRECT_URL']是Apache重写后生成的变量,存储的就是重写后的路径(比如/download/epub)
  • 通过Flight::set('flight.request.url', ...)强制Flight使用重写后的路径,这样路由才能正确匹配

三、额外注意事项

  • 确保你的Apache配置中AllowOverride All已开启,否则.htaccess文件的规则不会生效
  • 测试时可以先在Flight路由中打印var_dump($_SERVER),确认REDIRECT_URL和REQUEST_URI的取值,确保拿到的是重写后的路径
  • 注意服务器文件权限,确保PHP有读取epub/mobi文件的权限

内容的提问来源于stack exchange,提问作者Marek Jedliński

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.21 07:35:10