首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 網頁程式設計 >> PHP 程式設計 >> PHP 相關知識

PHP 偽靜態技術原理與實現方式全解析

     編輯:PHP 相關知識

偽靜態技術將動態 URL(如 index.php?id=1)轉換為靜態化形式(如 article-1.html),兼顧 SEO 友善與動態處理彈性。本文系統整理五種主流實現方案,並說明偽靜態對安全測試的影響。

核心原理

Web 伺服器(Apache/Nginx)或 PHP 應用層攔截請求,依規則將「靜態風格 URL」重寫/解析為「動態參數 URL」,再交由 PHP 處理。瀏覽器與使用者僅見靜態化 URL。

方案一:Apache mod_rewrite(最常用、效能最佳)

# .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 對應參數
  • 規則優先序需注意,避免靜態資源(css/js/圖片)被誤導向

方案二:PHP 解析 REQUEST_URI(編碼分隔符)

$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];
}

方案三:PHP 解析 PATH_INFO(/test.php/1/2)

$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。

方案四:通用 mod_rewrite 函式封裝

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;
}

方案五:固定格式正則解析(/1,100,8630.html)

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 環境下的偽靜態配置

# nginx.conf
location / {
    try_files $uri $uri/ /index.php?$query_string;
    # 或特定規則
    rewrite ^/article-(\d+)\.html$ /index.php?action=article&id=$1 last;
}

安全測試視角:偽靜態與 SQL 注入

偽靜態不增加 SQL 注入防禦能力。參數最終仍進入 $_GET,注入點依然存在。安全測試時需針對重寫後的真實參數進行測試,或構造中轉頁面(如文中 inj.php 代理請求)配合掃描工具。

總結與選型建議

  • Apache + mod_rewrite:效能最佳、規則靈活、生產環境首選
  • Nginx rewrite:語法簡潔、效能優異、現代主流選擇
  • PHP 層解析:無需伺服器配置權限、適用虛擬主機、但效能較差且邏輯分散
  • 框架路由:Laravel/ThinkPHP/Symfony 內建路由元件,統一管理、支援中介軟體、最佳開發體驗

現代專案強烈建議使用框架路由或 Nginx/Apache 伺服器層重寫,避免在 PHP 代碼中手工解析 URL,減少維護成本與潛在邏輯漏洞。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved