無需重寫規則,純 PHP 實現基於 PATH_INFO 的 MVC 風格路由解析,支持 .html、.do、.shtml、.aspx 等任意偽靜態後綴,並自動將參數映射到 $_GET 供框架使用。
$_SERVER['PATH_INFO'] 獲取 /index.php/module/action/param1/value1/... 路徑信息。/ 分割提取模塊、控制器、動作及參數。<?php
// 路由解析入口,放在框架啟動最早處
if (isset($_SERVER['PATH_INFO'])) {
// 1. 去除偽靜態後綴
$str = substr($_SERVER['PATH_INFO'], 0, strpos($_SERVER['PATH_INFO'], '.'));
// 2. 分割路徑
$pathinfo = explode('/', trim($str, '/'));
// 3. 映射模塊
$_GET['m'] = !empty($pathinfo[0]) ? $pathinfo[0] : 'index';
array_shift($pathinfo);
// 4. 映射控制器/動作
$_GET['a'] = !empty($pathinfo[0]) ? $pathinfo[0] : 'index';
array_shift($pathinfo);
// 5. 映射其餘參數
$num = count($pathinfo);
for ($i = 0; $i < $num; $i += 2) {
if (isset($pathinfo[$i + 1])) {
$_GET[$pathinfo[$i]] = $pathinfo[$i + 1];
}
}
} else {
// 兼容普通模式:自動重定向至偽靜態
$_GET['m'] = !empty($_GET['m']) ? $_GET['m'] : 'index';
$_GET['a'] = !empty($_GET['a']) ? $_GET['a'] : 'index';
if ($_SERVER['QUERY_STRING']) {
$m = $_GET['m']; unset($_GET['m']);
$a = $_GET['a']; unset($_GET['a']);
$query = http_build_query($_GET);
// 重點:構建偽靜態 URL
$url = $_SERVER['SCRIPT_NAME'] . "/{$m}/{$a}/" . str_replace(['&', '='], '/', $query) . ".html";
header("Location: " . $url);
exit;
}
}
| 訪問 URL | 解析後 $_GET |
|---|---|
| /index.php/user/profile/id/123.html | m=user, a=profile, id=123 |
| /index.php/api/v1/list/page/2/size/20.do | m=api, a=v1, list=page, 2=size, 20= (參數需成對) |
| /index.php?m=goods&a=detail&id=99 | 301 重定向至 /index.php/goods/detail/id/99.html |
.html,實際項目應從配置讀取。$_GET 直接用於控制器,建議增加 XSS/注入過濾中間件。location ~ \.php(/|$) 支持 PATH_INFO 透傳。生產環境建議使用成熟路由組件(如 FastRoute、Symfony Routing、League\Route),支持 RESTful、中間件、參數類型驗證、路由緩存等企業級特性。