.htaccess移除.php后缀与博客路由规则冲突问题排查
问题排查与修复
核心问题:Rewrite规则执行顺序与逻辑冲突
两个规则同时启用时路由失效,根源在于规则执行顺序错误和缺少必要的条件限制:
- 原配置中路由规则先执行,但未加
L标记,请求会继续匹配后续的.php后缀规则,把route.php?blog=xxx错误重写为route.php.php?blog=xxx,直接破坏路由逻辑。 .php后缀规则未排除真实存在的文件/目录,也未限制仅匹配无后缀请求,会干扰路由规则的正常执行。
修复后的.htaccess配置
调整规则顺序,给路由规则添加L标记终止后续匹配,同时为后缀规则补充条件,确保仅处理真实存在的.php文件:
Options +FollowSymLinks RewriteEngine On RewriteBase / # 优先处理博客路由:仅当请求不是真实文件/目录时,转发到route.php RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^([^?]*) route.php?blog=$1 [L] # 处理.php后缀隐藏:仅当请求无后缀且对应的.php文件存在时才重写 RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME}.php -f RewriteRule ^([^\.]+)$ $1.php [NC,L] # Error Documents #ErrorDocument 404 /error_404.php #ErrorDocument 403 /error_403.php
关键调整说明:
- 将路由规则前置,确保博客类请求优先被处理,
[L]标记会终止后续规则匹配,避免请求被二次修改。 - 给后缀规则添加
%{REQUEST_FILENAME}.php -f条件,仅当对应的.php文件真实存在时才执行重写,彻底避免干扰路由请求。
PHP代码中的潜在问题修复
1. 语法错误
include语句缺少字符串连接符.,会导致语法报错:
原错误代码:
include($_SERVER['DOCUMENT_ROOT']"/config.php"); // ... include($doc_path"/blog-single.php");
修复后:
include($_SERVER['DOCUMENT_ROOT'] . "/config.php"); // ... include($doc_path . "/blog-single.php");
2. 严重SQL注入风险
直接将用户输入的$blog[2]拼入SQL语句,极易被注入攻击,必须使用参数化查询:
原风险代码:
$sql = "select * from articles a, categories c where a.cat = c.catid and a.id = '" . $blog[2] . "' limit 0,1"; $res = $db->query($sql);
修复为参数化查询:
$stmt = $db->prepare("select * from articles a, categories c where a.cat = c.catid and a.id = ? limit 0,1"); $stmt->bind_param("i", $blog[2]); // "i"表示参数为整数类型 $stmt->execute(); $res = $stmt->get_result(); $rowcount = $res->num_rows;
3. 变量覆盖问题
在case 3中,你将$blog从数组覆盖为查询结果数组:
$blog = mysqli_fetch_assoc($res);
若查询无结果,$blog会保持原数组状态,后续代码可能出现逻辑错误,建议重命名变量避免覆盖:
$blog_data = mysqli_fetch_assoc($res); include($doc_path . "/blog-single.php");
同时修改blog-single.php中的变量引用为$blog_data['id'],并同样使用参数化查询避免注入:
$stmt = $db->prepare("select * from categories c, articles a, relatedposts r where r.related_blog = ? and a.id = r.related_post and c.catid = a.cat order by a.datetime"); $stmt->bind_param("i", $blog_data['id']); $stmt->execute(); $rows = $stmt->get_result(); $found = $rows->num_rows;
内容的提问来源于stack exchange,提问作者jww241
相关产品推荐
相关产品推荐

