.htaccess参数转路径规则在Hostinger主机失效的问题排查
问题:Hostinger主机上.htaccess URL重写规则失效
我需要通过.htaccess实现URL参数转路径,示例:https://test.link?test123 → https://test.link/test123。网站运行PHP 8.0环境,本地使用的.htaccess规则如下:
RewriteEngine on [...] RewriteCond $1 !^(index\.php) RewriteCond ${REQUEST_FILENAME} !-f RewriteCond ${REQUEST_FILENAME} !-d RewriteRule ^(.*)$ index.php?/$1 [L]
该规则在本地正常生效,但部署到Hostinger主机后无法工作。请问是否需要启用/禁用相关插件,或是该规则被Hostinger限制?同时附上我的index.php代码供参考:
<?php require_once 'database.php'; # 仅用于连接数据库,工作正常 $new_uri = ""; if(!empty($_GET)){ foreach($_GET as $key => $val){ $u = $key; $new_uri = str_replace('/', '', $u); $sql = "[...]"; $stmt = mysqli_stmt_init($connect); if(mysqli_stmt_prepare($stmt, $sql)){ mysqli_stmt_bind_param($stmt, "s", $new_uri); mysqli_stmt_execute($stmt); $resultData = mysqli_stmt_get_result($stmt); $resultnum = mysqli_num_rows($resultData); if($resultnum > 0){ $c_query = "[...]"; $stmts = mysqli_stmt_init($connect); if(mysqli_stmt_prepare($stmts, $c_query)){ mysqli_stmt_bind_param($stmts, "s", $new_uri); mysqli_stmt_execute($stmts); mysqli_stmt_close($stmts); }else{ echo "<h1>Error</h1>"; http_response_code(500); exit(); } if($row = mysqli_fetch_assoc($resultData)){ $long_url = $row["long_url"]; header("Location: " . $long_url); }else{ echo "<h1>Error - unknown error</h1>"; exit(); } }else{ echo "<h1>Error</h1>"; exit; } mysqli_stmt_close($stmt); }else{ http_response_code(500); echo "<h1>Error</h1>"; exit(); } } }else{ echo "<h1>File / not found</h1>"; exit; } ?>
解决方案
1. 适配Hostinger的.htaccess规则调整
Hostinger的Apache配置对重写规则的解析逻辑略有不同,修改规则为以下版本即可适配:
RewriteEngine On # 排除index.php本身 RewriteCond %{REQUEST_URI} !^/index\.php$ # 跳过真实存在的文件和目录 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # 将请求转发到index.php,传递路径作为参数 RewriteRule ^(.*)$ index.php?$1 [QSA,L]
- 移除原规则中
?/的斜杠,避免PHP参数解析异常 - 添加
QSA标志,确保原有URL参数不会丢失(若有需求) - 优化条件匹配逻辑,提升规则严谨性
2. Hostinger后台必要设置检查
- 确认mod_rewrite启用:登录Hostinger后台,进入「网站」→「管理网站」→「高级」→「Apache & Nginx」,确保
mod_rewrite处于启用状态(Hostinger默认开启,部分套餐需手动勾选) - 验证根目录路径:确认网站根目录指向
public_html(Hostinger默认根目录),.htaccess必须放在根目录下才能全局生效 - 临时禁用缓存插件:若安装了缓存类插件(如WP Rocket),暂时禁用测试,避免缓存覆盖重写规则
3. PHP代码适配优化
原代码依赖$_GET键值获取路径,在Hostinger环境下可能因参数解析逻辑失效,建议直接通过服务器变量获取路径:
<?php require_once 'database.php'; // 直接获取请求路径并过滤非法字符 $new_uri = trim($_SERVER['REQUEST_URI'], '/'); $new_uri = preg_replace('/[^a-zA-Z0-9\-_]/', '', $new_uri); if(!empty($new_uri)){ $sql = "[...]"; $stmt = mysqli_stmt_init($connect); if(mysqli_stmt_prepare($stmt, $sql)){ mysqli_stmt_bind_param($stmt, "s", $new_uri); mysqli_stmt_execute($stmt); $resultData = mysqli_stmt_get_result($stmt); $resultnum = mysqli_num_rows($resultData); if($resultnum > 0){ $c_query = "[...]"; $stmts = mysqli_stmt_init($connect); if(mysqli_stmt_prepare($stmts, $c_query)){ mysqli_stmt_bind_param($stmts, "s", $new_uri); mysqli_stmt_execute($stmts); mysqli_stmt_close($stmts); }else{ echo "<h1>Error</h1>"; http_response_code(500); exit(); } if($row = mysqli_fetch_assoc($resultData)){ $long_url = $row["long_url"]; header("Location: " . $long_url); exit(); }else{ echo "<h1>Error - unknown error</h1>"; exit(); } }else{ echo "<h1>Error</h1>"; exit; } mysqli_stmt_close($stmt); }else{ http_response_code(500); echo "<h1>Error</h1>"; exit(); } }else{ echo "<h1>File / not found</h1>"; exit; } ?>
- 直接从
$_SERVER['REQUEST_URI']获取路径,避免依赖$_GET解析逻辑 - 添加非法字符过滤,提升代码安全性
4. 排查与测试
- 直接访问
https://test.link/test123,验证是否正常跳转 - 在index.php顶部添加
var_dump($_SERVER);,查看服务器传递的参数是否符合预期,确认重写规则是否生效 - 查看Hostinger错误日志(后台「网站」→「管理网站」→「统计」→「错误日志」),定位重写规则相关报错
内容的提问来源于stack exchange,提问作者Baum
相关产品推荐
相关产品推荐

