如何使用PHP与.htaccess为多页面配置URL重写规则
嘿,看来你已经搞定了单条URL重写,现在想扩展到多种场景对吧?我结合你给出的PHP代码,整理了几种实用的多URL重写实现方案,帮你把网站的URL变得更友好规范。
多种URL重写实现方案
首先先把你未完成的php_slug函数补全,确保生成的URL slug规范无冗余:
function php_slug($string) { list($packageid, $packagename) = explode(":",$string); $url = $packageid."/".strtolower(str_replace(' ', '-', $packagename)); // 过滤非法字符,合并多余连字符 $slug = preg_replace('/[^a-z0-9-]+/', '-', trim(strtolower($url))); $slug = preg_replace('/-+/', '-', $slug); return rtrim($slug, '-'); }
1. 包详情页重写(你的现有场景扩展)
这是你当前正在用的package/{package-id}/{package-name}格式,完善后的规则和PHP处理逻辑如下:
.htaccess 规则
RewriteEngine On # 开启重写引擎 RewriteBase / # 处理包详情页的友好URL RewriteRule ^package/([0-9]+)/([a-z0-9-]+)$ index.php?package_id=$1&package_slug=$2 [L,QSA]
[L]表示这是最后一条规则,匹配后不再执行后续规则[QSA]表示保留原URL的查询参数(如果有的话)
PHP 处理逻辑(index.php中)
session_start(); // 处理重写后的包详情请求 if(isset($_GET['package_id'])) { $packageId = intval($_GET['package_id']); $packageSlug = $_GET['package_slug'] ?? ''; // 可选:验证slug合法性,防止恶意构造URL // 示例:从数据库获取包信息,对比生成的slug是否匹配 // $package = getPackageFromDB($packageId); // $expectedSlug = php_slug($package['id'].':'.$package['name']); // if($expectedSlug !== "$packageId/$packageSlug") { // header("HTTP/1.1 404 Not Found"); // exit; // } // 这里写包详情页的渲染逻辑 } // 你原有的表单提交跳转逻辑 if(isset($_POST["packagestring"])) { $retvalue = $_POST["packagestring"]; $_SESSION["package_string"] = $retvalue; $slug = php_slug($retvalue); header("Location: package/".$slug); exit; // 跳转后必须终止代码执行,避免后续逻辑干扰 } // 补全的slug生成函数 function php_slug($string) { list($packageid, $packagename) = explode(":",$string); $url = $packageid."/".strtolower(str_replace(' ', '-', $packagename)); $slug = preg_replace('/[^a-z0-9-]+/', '-', trim(strtolower($url))); $slug = preg_replace('/-+/', '-', $slug); return rtrim($slug, '-'); }
2. 分类列表页重写
如果你的网站有分类模块,可以添加这种友好URL规则:
.htaccess 规则
# 处理分类列表页 RewriteRule ^category/([a-z0-9-]+)$ index.php?category_slug=$1 [L,QSA]
PHP 处理逻辑
if(isset($_GET['category_slug'])) { $categorySlug = $_GET['category_slug']; // 根据slug从数据库获取分类信息,渲染该分类下的包列表 // $category = getCategoryBySlug($categorySlug); // $packages = getPackagesByCategory($category['id']); }
3. 静态页面重写(如关于我们、联系方式)
对于静态页面,也可以用简洁的URL代替带参数的地址:
.htaccess 规则
# 处理静态页面 RewriteRule ^page/([a-z0-9-]+)$ index.php?page_slug=$1 [L,QSA]
PHP 处理逻辑
if(isset($_GET['page_slug'])) { $pageSlug = $_GET['page_slug']; // 根据slug加载对应静态页面 switch($pageSlug) { case 'about': include 'pages/about.php'; break; case 'contact': include 'pages/contact.php'; break; default: header("HTTP/1.1 404 Not Found"); exit; } }
4. 分页URL重写
如果列表有分页需求,优化后的分页URL会更美观:
.htaccess 规则
# 分类列表分页 RewriteRule ^category/([a-z0-9-]+)/page/([0-9]+)$ index.php?category_slug=$1&page=$2 [L,QSA] # 全部包列表分页 RewriteRule ^packages/page/([0-9]+)$ index.php?page=$1 [L,QSA]
PHP 处理逻辑
$currentPage = $_GET['page'] ?? 1; $currentPage = max(1, intval($currentPage)); // 确保页码为正整数 // 分页查询数据 // $packages = getPackagesByPage($currentPage, 10); // 10为每页条数
关键注意事项
- 确保Apache服务器开启了
mod_rewrite模块,虚拟主机配置中设置了AllowOverride All(允许.htaccess生效) - 如果是Nginx环境,需要将Apache的rewrite规则转换成Nginx语法,比如包详情页的规则:
rewrite ^/package/([0-9]+)/([a-z0-9-]+)$ /index.php?package_id=$1&package_slug=$2 last; - 所有跳转操作后必须添加
exit;或die();,防止后续代码执行 - 对重写后的参数要做合法性校验,比如
package_id必须是数字,避免SQL注入或恶意请求
内容的提问来源于stack exchange,提问作者Partap
相关产品推荐
相关产品推荐

