偽靜態技術將動態 URL(如 index.php?id=1)轉換為靜態化形式(如 article-1.html),兼顧 SEO 友善與動態處理彈性。本文系統整理五種主流實現方案,並說明偽靜態對安全測試的影響。
Web 伺服器(Apache/Nginx)或 PHP 應用層攔截請求,依規則將「靜態風格 URL」重寫/解析為「動態參數 URL」,再交由 PHP 處理。瀏覽器與使用者僅見靜態化 URL。
# .htaccess 或 httpd.conf
RewriteEngine on
# 規則:page-18.html → index.php?action=page&id=18
RewriteRule ([a-zA-Z]{1,})-([0-9]{1,})\.html$ index.php?action=$1&id=$2
mod_rewrite 模組與 AllowOverride All$1、$2 對應參數$Php2Html_FileUrl = $_SERVER["REQUEST_URI"];
// 例:/test.php?id|1@action|2
$Php2Html_UrlString = str_replace("?", "", str_replace("/", "", strrchr(strrchr($Php2Html_FileUrl, "/"), "?")));
// 內層 strrchr → /test.php?id|1@action|2
// 外層 strrchr → id|1@action|2
// 移除 / 和 ? → id|1@action|2
$Php2Html_UrlQueryStrList = explode("@", $Php2Html_UrlString); // [id|1, action|2]
foreach ($Php2Html_UrlQueryStrList as $Php2Html_UrlQueryStr) {
$Php2Html_TmpArray = explode("|", $Php2Html_UrlQueryStr);
$_GET[$Php2Html_TmpArray[0]] = $Php2Html_TmpArray[1];
}
$filename = basename($_SERVER["SCRIPT_NAME"]);
if (strtolower($filename) == 'test.php') {
if (!empty($_GET['id'])) {
// 正常參數模式
$id = intval($_GET['id']);
$action = intval($_GET['action']);
} else {
// PATH_INFO 模式:/test.php/1/2
$nav = $_SERVER["REQUEST_URI"];
$script = $_SERVER["SCRIPT_NAME"];
$nav = ereg_replace("$script", "", urldecode($nav)); // 剩下 /1/2
$vars = explode("/", $nav);
$id = intval($vars[1]);
$action = intval($vars[2]);
}
}
需 PHP 設定 cgi.fix_pathinfo=1,且伺服器支援 PATH_INFO。
function mod_rewrite() {
global $_GET;
$nav = $_SERVER["REQUEST_URI"];
$script_name = $_SERVER["SCRIPT_NAME"];
$nav = substr(ereg_replace("$script_name", "", urldecode($nav)), 1);
$nav = preg_replace("/^.ht(m){1}(l){0,1}$/", "", $nav); // 去除 .html/.htm
$vars = explode("/", $nav);
for ($i = 0; $i < count($vars); $i += 2) {
$_GET[$vars[$i]] = $vars[$i + 1];
}
return $_GET;
}
if (preg_match("/\/(\d+),(\d+),(\d+)\.html/si", $path_info, $arr_path)) {
$gid = intval($arr_path[1]); // 1
$sid = intval($arr_path[2]); // 100
$softid = intval($arr_path[3]); // 8630
} else {
echo "Path:Error!";
}
# nginx.conf
location / {
try_files $uri $uri/ /index.php?$query_string;
# 或特定規則
rewrite ^/article-(\d+)\.html$ /index.php?action=article&id=$1 last;
}
偽靜態不增加 SQL 注入防禦能力。參數最終仍進入 $_GET,注入點依然存在。安全測試時需針對重寫後的真實參數進行測試,或構造中轉頁面(如文中 inj.php 代理請求)配合掃描工具。
現代專案強烈建議使用框架路由或 Nginx/Apache 伺服器層重寫,避免在 PHP 代碼中手工解析 URL,減少維護成本與潛在邏輯漏洞。