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

PHP 偽靜態技術原理與實現五種方案:Apache Rewrite、PATH_INFO、正則解析、路由映射完整教學

     編輯:PHP 綜合知識

偽靜態將動態 URL (index.php?id=1) 重寫為靜態風格 (/article/1.html),利於 SEO、美觀、隱藏技術細節。本文詳解五種實現方案:Apache mod_rewrite、Nginx rewrite、PHP PATH_INFO 解析、自定義路由類、框架級路由,並說明 SQL 注入繞過風險與防護。

方案一:Apache mod_rewrite (最常用)

啟用模組

# httpd.conf
LoadModule rewrite_module modules/mod_rewrite.so
AllowOverride All  # 允許 .htaccess

.htaccess 規則

RewriteEngine On
# 將 /article/123.html 重寫為 index.php?action=article&id=123
RewriteRule ^([a-zA-Z]+)-([0-9]+)\.html$ index.php?action=$1&id=$2 [L,QSA]

# 通用:所有非實體檔案導向 index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php/$1 [L,QSA]

方案二:Nginx rewrite (高效能)

# nginx.conf
location / {
    try_files $uri $uri/ /index.php$is_args$args;
}

# 或特定規則
location / {
    rewrite ^/([a-z]+)-([0-]+)\.html$ /index.php?action=$1&id=$2 last;
}

方案三:PHP PATH_INFO 解析 (無需 Web Server 配置)

URL 格式:https://domain.com/index.php/article/123

<?php
// 入口檔 index.php
$pathInfo = $_SERVER['PATH_INFO'] ?? '/'; // /article/123
$pathInfo = trim($pathInfo, '/');
$segments = explode('/', $pathInfo);

$action = $segments[0] ?? 'index';
$id     = $segments[1] ?? 0;

// 派發
include "controllers/{$action}.php";

注意: 部分需在 php.ini 設定 cgi.fix_pathinfo=1,Nginx 需 fastcgi_param PATH_INFO $fastcgi_path_info;。

方案四:自定義路由類 (框架雛形)

<?php
class Router {
    private $routes = [];

    public function get($pattern, $handler) {
        $this->routes['GET'][$pattern] = $handler;
    }

    public function dispatch() {
        $method = $_SERVER['REQUEST_METHOD'];
        $uri = parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH);
        
        foreach ($this->routes[$method] ?? [] as $pattern => $handler) {
            // 簡易正則轉換:/article/{id:\d+} → 正則
            $regex = preg_replace('/\{(\w+)(?::([^}]+))?\}/', '(?P<$1>$2)', $pattern);
            $regex = '@^' . $regex . '$@';
            
            if (preg_match($regex, $uri, $matches)) {
                // 過濾數字索引,保留命名捕獲
                $params = array_filter($matches, 'is_string', ARRAY_FILTER_USE_KEY);
                return call_user_func_array($handler, $params);
            }
        }
        http_response_code(404);
        echo 'Not Found';
    }
}

// 使用
$router = new Router();
$router->get('/article/{id:\d+}', function($id) {
    echo "Article ID: $id";
});
$router->dispatch();

方案五:框架級路由 (Laravel/ThinkPHP/Symfony 風格)


// Laravel 風格 routes/web.php
Route::get('/article/{id}', 'ArticleController@show');
Route::post('/article', 'ArticleController@store');

// 對應控制器
class ArticleController {
    public function show($id) {
        return Article::findOrFail($id);
    }
}

偽靜態與 SQL 注入風險

原文提到利用偽靜態中轉頁面繞過 WAF 注入檢測:

<?php
// inj.php - 危險範例(僅供理解原理,嚴禁生產使用)
$id = $_GET['id'];
$url = "https://target.com/index.php/library/more/id/$id.html";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
echo curl_exec($ch);

防護:

  • 參數化查詢 / Prepared Statement (根本解決)
  • WAF 規則檢測 curl/file_get_contents 異常外連
  • 嚴格驗證偽靜態參數格式(如 id 必須純數字)

方案選擇建議

場景推薦方案理由
Apache 虛擬主機、共享主機.htaccess mod_rewrite無需 root 權限、相容性佳
Nginx + PHP-FPM 生產環境Nginx rewrite + try_files效能最佳、配置集中
快速原型、無法修改 Web ServerPATH_INFO零配置、PHP 內部解析
中大型專案、長期維護框架級路由結構化、中介軟體、測試友善

總結

偽靜態本質是 URL 重寫 + 參數解析 + 路由派發。現代專案建議直接使用成熟框架路由系統,手動實作僅適合學習或極輕量專案。無論何種方案,**輸入驗證與參數化查詢** 才是資安根本。

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