如何通过.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
相关产品推荐
相关产品推荐

