路由機制的核心在於將特定格式的 URL 結構轉換為系統可識別的參數,並能反向生成友善的 URL。以 https://main.test.com/article/1 為例,路由會將 /article/1 解析為 ?_m=article&id=1,方便程式內部處理;反之,也能根據參數生成乾淨的 URL 結構。
透過 index.php?c=index&m=index 這類查詢字串,直接對應控制器與方法。簡單直觀,但 URL 不夠美觀,且對 SEO 不利。
利用 Apache mod_rewrite 或 Nginx 規則,將非 PHP 結尾的請求導向入口檔案。典型的 .htaccess 設定如下:
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteRule ^index\.php$ - [L]
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
優點:URL 乾淨、可隱藏副檔名、利於 SEO;缺點:需伺服器支援 Rewrite 模組。
URL 形式如 xxx.com/index.php/c/index/aa/cc,Apache 會將 index.php 後的部分存入 $_SERVER['PATH_INFO'],由 PHP 解析分發。此模式相容性佳,無需額外伺服器設定。
RewriteEngine on
RewriteRule ([a-zA-Z]{1,})-([0-9]{1,}).html$ sharexie/test.php?action=$1&id=$2
將 view-12.html 重寫為 sharexie/test.php?action=view&id=12。
<?php
echo '你的Action是:' . $_GET['action'];
echo '<br/>';
echo '你的ID是:' . $_GET['id'];
?>
核心邏輯:獲取 $_SERVER['REQUEST_URI'],移除專案路徑前綴,按 / 分割為控制器、方法與參數,再動態載入類別並呼叫方法。
<?php
error_reporting(0);
date_default_timezone_set("Asia/Shanghai");
$_DocumentPath = $_SERVER['DOCUMENT_ROOT'];
$_RequestUri = $_SERVER['REQUEST_URI'];
$_UrlPath = $_RequestUri;
$_FilePath = __FILE__;
$_AppPath = str_replace($_DocumentPath, '', $_FilePath);
$_AppPathArr = explode(DIRECTORY_SEPARATOR, $_AppPath);
for ($i = 0; $i < count($_AppPathArr); $i++) {
$p = $_AppPathArr[$i];
if ($p) {
$_UrlPath = preg_replace('/^\/'.$p.'\//', '/', $_UrlPath, 1);
}
}
$_UrlPath = preg_replace('/^\//', '', $_UrlPath, 1);
$_AppPathArr = explode("/", $_UrlPath);
$_AppPathArr_Count = count($_AppPathArr);
$arr_url = array(
'controller' => 'sharexie/test',
'method' => 'index',
'parms' => array()
);
$arr_url['controller'] = $_AppPathArr[0];
$arr_url['method'] = $_AppPathArr[1];
if ($_AppPathArr_Count > 2 and $_AppPathArr_Count % 2 != 0) {
die('參數錯誤');
} else {
for ($i = 2; $i < $_AppPathArr_Count; $i += 2) {
$arr_temp_hash = array(strtolower($_AppPathArr[$i]) => $_AppPathArr[$i + 1]);
$arr_url['parms'] = array_merge($arr_url['parms'], $arr_temp_hash);
}
}
$module_name = $arr_url['controller'];
$module_file = $module_name.'.class.php';
$method_name = $arr_url['method'];
if (file_exists($module_file)) {
include $module_file;
$obj_module = new $module_name();
if (!method_exists($obj_module, $method_name)) {
die("要調用的方法不存在");
} else {
if (is_callable(array($obj_module, $method_name))) {
$obj_module -> $method_name($module_name, $arr_url['parms']);
$obj_module -> printResult();
}
}
} else {
die("定義的模塊不存在");
}
?>
| 旗標 | 說明 |
|---|---|
| R | 強制外部重定向 |
| F | 禁用 URL,返回 403 |
| G | 強制 URL 為 GONE,返回 410 |
| P | 強制使用代理轉發 |
| L | 最後一條規則,停止後續匹配 |
| N | 重新從第一條規則開始 |
| C | 與下一條規則關聯 |
| T=MIME-type | 強制 MIME 類型 |
| NS | 僅用於非內部子請求 |
| NC | 不區分大小寫 |
| QSA | 追加查詢字串 |
| NE | 不轉義特殊字符 |
掌握 PHP 路由的三種模式與實作細節,能讓你靈活設計 RESTful API 或 MVC 架構。實務上建議採用 URL Rewrite + 入口檔案分發 的模式,兼顧效能、安全與 SEO。