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

PHP + Apache 實現 URL 偽靜態完整指南:mod_rewrite 配置、.htaccess 編寫與 Nginx 遷移方案

     編輯:PHP 相關知識

PHP + Apache 實現 URL 偽靜態完整指南:mod_rewrite 配置、.htaccess 編寫與 Nginx 遷移方案

偽靜態(URL Rewrite)是現代 Web 應用的標配,能提升 SEO、隱藏技術細節、美化 URL。本文系統講解 Apache mod_rewrite 配置全流程、正則規則編寫技巧、常見框架遷移方案與 Nginx 對照配置。

核心原理

客戶端請求靜態化 URL(如 /article/123.html)→ Apache mod_rewrite 攔截 → 內部重寫為動態腳本(/index.php?action=article&id=123)→ PHP 處理返回內容 → 客戶端瀏覽器地址欄保持原 URL。

Apache 環境準備

1. 啟用 mod_rewrite 模組

# httpd.conf
LoadModule rewrite_module modules/mod_rewrite.so  # 取消註釋

# 或動態載入
# LoadModule rewrite_module /usr/lib/apache2/modules/mod_rewrite.so

驗證:phpinfo() → Loaded Modules 搜尋 mod_rewrite,或 apachectl -M | grep rewrite

2. 允許 .htaccess 覆蓋

# httpd.conf

    Options FollowSymLinks
    AllowOverride All  # 關鍵:允許 .htaccess 覆蓋 RewriteRule
    Require all granted

.htaccess 核心配置

# .htaccess 置於網站根目錄
RewriteEngine On

# 1. 防止訪問隱藏檔案
RewriteRule ^\.(.*)$ - [F,L]

# 2. 靜態資源直接服務(不經 PHP)
RewriteCond %{REQUEST_FILENAME} -f [OR]
RewriteCond %{REQUEST_FILENAME} -d
RewriteRule ^ - [L]

# 3. 核心重寫規則:所有非靜態請求轉發到 index.php
RewriteRule ^(.*)$ index.php [QSA,L]

# QSA (Query String Append):保留原查詢字串
# L (Last):停止後續規則處理

進階重寫規則範例

1. MVC 框架標準路由

# /controller/action/params → index.php?c=controller&a=action¶ms
RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)(/.*)?$ index.php?c=$1&a=$2$3 [QSA,L]

# 實際匹配:
# /user/login → c=user, a=login
# /article/view/123 → c=article, a=view, /123

2. RESTful 風格 API

# GET    /api/users           → index.php?resource=users&action=list
# GET    /api/users/123       → index.php?resource=users&action=get&id=123
# POST   /api/users           → index.php?resource=users&action=create
# PUT    /api/users/123       → index.php?resource=users&action=update&id=123
# DELETE /api/users/123       → index.php?resource=users&action=delete&id=123

RewriteRule ^api/([a-zA-Z0-9_-]+)/?$ index.php?resource=$1&action=list [QSA,L]
RewriteRule ^api/([a-zA-Z0-9_-]+)/([0-9]+)/?$ index.php?resource=$1&action=get&id=$2 [QSA,L]
# POST/PUT/DELETE 需在 PHP 中根據 $_SERVER['REQUEST_METHOD'] 判斷

3. 偽靜態 HTML 後綴(SEO 友好)

# /article-123.html → index.php?action=article&id=123
RewriteRule ^([a-zA-Z0-9_-]+)-([0-9]+)\.html$ index.php?action=$1&id=$2 [QSA,L]

# /category/news/page-2.html → index.php?cat=news&page=2
RewriteRule ^category/([a-zA-Z0-9_-]+)/page-([0-9]+)\.html$ index.php?cat=$1&page=$2 [QSA,L]

4. 多語言/子目錄站點

# /zh/article/123 → index.php?lang=zh&c=article&a=view&id=123
RewriteRule ^(zh|en|ja)/([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)(/.*)?$ index.php?lang=$1&c=$2&a=$3$4 [QSA,L]

正則表達式速查與最佳實踐

模式含義範例匹配
[a-zA-Z0-9_-]+字母、數字、底線、連字符,至少一個user-center, article_123
[0-9]+純數字,至少一位123, 0, 99999
(.*)任意字元(含空),貪婪匹配/foo/bar/baz
(.*?)任意字元,非貪婪匹配盡可能少匹配
\.字面點號(需轉義).html, .php
^...$錨定開頭結尾,精確匹配防止部分匹配

常用 Rewrite 旗標

  • [L] / [last]:停止處理後續規則
  • [QSA] / [qsappend]:追加原查詢字串
  • [R=301] / [redirect=301]:外部重定向(瀏覽器地址變化)
  • [NC] / [nocase]:大小寫不敏感
  • [F] / [forbidden]:返回 403
  • [G] / [gone]:返回 410
  • [P] / [proxy]:代理請求(需 mod_proxy)
  • [E=VAR:VAL] / [env=VAR:VAL]:設定環境變數

PHP 端獲取重寫後參數

<?php
// index.php 入口
$requestUri = $_SERVER['REQUEST_URI']; // /article-123.html?source=seo
$scriptName = $_SERVER['SCRIPT_NAME']; // /index.php

// 解析路由
$route = parse_url($requestUri, PHP_URL_PATH); // /article-123.html
$query = parse_url($requestUri, PHP_URL_QUERY); // source=seo

// 配合 .htaccess 規則解析
if (preg_match('#^([a-zA-Z0-9_-]+)-([0-9]+)\.html$#', $route, $matches)) {
    $action = $matches[1]; // article
    $id = (int)$matches[2]; // 123
    parse_str($query, $queryParams);
    // 現在有 $action, $id, $queryParams['source']
}

虛擬主機配置(生產環境推薦)

# /etc/apache2/sites-available/example.com.conf

    ServerName example.com
    ServerAlias www.example.com
    DocumentRoot /var/www/example.com/public
    
    
        Options -Indexes +FollowSymLinks
        AllowOverride All
        Require all granted
    
    
    # 直接在 VirtualHost 寫規則(效能優於 .htaccess)
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^ index.php [QSA,L]
    
    ErrorLog ${APACHE_LOG_DIR}/example.com_error.log
    CustomLog ${APACHE_LOG_DIR}/example.com_access.log combined

優勢:避免 Apache 遍歷目錄尋找 .htaccess,效能提升 10-20%。

Nginx 遷移對照配置

# Nginx 對應配置
server {
    listen 80;
    server_name example.com;
    root /var/www/example.com/public;
    index index.php;
    
    # 靜態資源直接服務
    location / {
        try_files $uri $uri/ /index.php?$query_string;
    }
    
    # PHP 處理
    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.1-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_intercept_errors on;
    }
    
    # 隱藏檔案保護
    location ~ /\.(?!well-known) {
        deny all;
    }
}

核心差異: Apache 用 RewriteRule 正則重寫,Nginx 用 try_files 靜態檢查 + 回退到 PHP,語義更清晰、效能更高。

除錯技巧

  1. 開啟重寫日誌(Apache 2.4+):LogLevel alert rewrite:trace3
  2. 測試規則:RewriteLog "/var/log/apache2/rewrite.log"(舊版)
  3. 線上測試工具:htaccess.madewithlove.be
  4. PHP 端除錯:var_dump($_SERVER['REQUEST_URI'], $_GET, $_POST)

遷移清單:從 Apache 到 Nginx

[ ] 將 .htaccess RewriteRule 轉換為 try_files + location
[ ] 正則捕獲組 $1 $2 → Nginx $1 $2 (相容)
[ ] QSA 旗標 → $query_string 變數自動保留
[ ] R=301 重定向 → return 301 /new-url;
[ ] 環境變數 E=VAR → fastcgi_param VAR value;
[ ] 拒絕訪問 [F] → deny all; / return 403;
[ ] 代理 [P] → proxy_pass https://backend;
[ ] 虛擬主機配置分離
[ ] 測試所有路由、靜態資源、PHP 執行、錯誤頁面

掌握 mod_rewrite 正則規則編寫與 Apache/Nginx 雙平台配置,是 PHP 後端工程師的核心基本功。建議新專案直接採用 Nginx + PHP-FPM 架構,遺留 Apache 專案按需遷移。

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