如何自动实现基于数据库文章标题的博客URL Rewriting?
当然可以!用数据库驱动的URL重写才是长期解决方案
你之前用PHP修改.htaccess的做法确实不推荐——不仅有文件权限风险,而且随着文章增多,.htaccess会变得臃肿不堪。基于数据库存储的文章别名(slug)来实现通用重写才是正确的思路,这也是几乎所有主流CMS的标准做法。下面是具体的实现步骤:
1. 配置通用的.htaccess重写规则
首先,只需要在你的根目录下写一次.htaccess规则,以后不管新增多少文章都不用再修改它:
RewriteEngine On # 排除实际存在的文件和目录(比如图片、CSS、JS文件) RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d # 将 /article/xxx 转发到 article.php?slug=xxx RewriteRule ^article/([^/]+)$ article.php?slug=$1 [L,QSA]
- 解释:
([^/]+)是正则表达式,匹配任意不含斜杠的字符串(也就是你的文章别名name_of_the_post),并将其作为slug参数传递给article.php。 [L,QSA]标记:L表示这是最后一条规则,QSA表示保留原URL中的其他查询参数(如果有的话)。
2. 数据库层面的准备
在你的文章表(比如articles)中添加一个slug字段:
- 字段类型推荐用
VARCHAR(255),并且设置为唯一索引(确保每个文章的别名不会重复)。 - 发布文章时,自动生成对应的slug:比如把文章标题转成小写,替换空格为连字符,去掉特殊字符。举个PHP示例:
function generateSlug($title) { $slug = strtolower(trim($title)); $slug = preg_replace('/[^a-z0-9-]/', '', str_replace(' ', '-', $slug)); // 可选:检查数据库中是否已有相同slug,如果有则追加数字(比如 xxx-2) return $slug; }
发布文章时调用这个函数,把生成的slug和文章内容一起存入数据库。
3. 修改article.php脚本,通过slug获取文章
现在article.php不再依赖id参数,而是通过slug从数据库查询文章:
<?php // 假设用PDO连接数据库(记得替换成你的数据库信息) $dsn = 'mysql:host=localhost;dbname=your_db;charset=utf8mb4'; $pdo = new PDO($dsn, 'username', 'password', [PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION]); if (isset($_GET['slug'])) { $slug = $_GET['slug']; // 用预处理语句防止SQL注入 $stmt = $pdo->prepare("SELECT * FROM articles WHERE slug = ?"); $stmt->execute([$slug]); $article = $stmt->fetch(PDO::FETCH_ASSOC); if ($article) { // 找到文章,输出内容 echo "<h1>" . htmlspecialchars($article['title']) . "</h1>"; echo "<div>" . $article['content'] . "</div>"; } else { // 找不到文章,返回404状态码 http_response_code(404); echo "<h1>404 - 文章不存在</h1>"; } } else { // 没有slug参数,返回首页或者404 header("Location: /"); exit; } ?>
额外的最佳实践
- 处理旧URL的兼容性:如果之前的
?id=3这类URL还有人访问,可以补充逻辑:当访问article.php?id=3时,查询对应的slug,然后重定向到/article/name_of_the_post,同时在.htaccess中添加辅助规则:# 重定向旧的?id=xxx到新的/article/slug RewriteCond %{QUERY_STRING} ^id=(\d+)$ RewriteRule ^article.php$ /article/%1? [R=301,L] - 确保mod_rewrite启用:如果是Apache服务器,需要确认
mod_rewrite模块已经启用,并且服务器允许.htaccess文件(配置AllowOverride All)。 - slug唯一性校验:生成slug时一定要检查数据库中是否已有相同的slug,避免冲突(比如两篇标题相同的文章,可以生成
my-post和my-post-2)。
内容的提问来源于stack exchange,提问作者R1'
相关产品推荐
相关产品推荐

