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

ThinkPHP URL 路由完全指南:規則、偽靜態、路由模式與最佳實踐

     編輯:PHP 綜合知識

前言

URL 路由是 MVC 框架的「交通指揮中心」,ThinkPHP 提供靈活的路由系統支援 RESTful、偽靜態、參數綁定、域名部署等高級特性。本文系統梳理 URL 訪問模式、路由配置語法、正則/選塊/資源路由、中介軟體整合、效能優化與遷移建議。

一、四大 URL 訪問模式

模式URL 範例特點適用場景
普通模式?m=Home&c=User&a=login相容性最好、無需 Web 伺服器配置開發測試、舊環境
PATHINFO/index.php/Home/User/login語義清晰、SEO 友好、無需 Rewrite大多數生產環境推薦
REWRITE/Home/User/login隱藏 index.php、最美觀生產環境 (需 Nginx/Apache 配置)
兼容模式?s=/Home/User/login不支援 PATHINFO 環境的折中特殊虛擬主機

配置切換 (config/app.php)

<?php
return [
    'url_route_on'           => true,   // 開啟路由
    'url_route_must'         => false,  // 強制使用路由 (true 時未匹配路由拋 404)
    'url_convert'            => true,   // 自動轉換控制器/方法名 (UserType -> user_type)
    'url_html_suffix'        => 'html', // 偽靜態後綴
    'url_common_param'       => false,  // 是否保留公共參數
];

二、路由定義完整語法 (ThinkPHP 5/6/8)

1. 基礎路由 (路由配置文件 route/app.php)

<?php
use think\facade\Route;

// 靜態地址路由
Route::get('login', 'user/login');
Route::post('register', 'user/register');

// 動態參數路由 (自動綁定到控制器方法參數)
Route::get('user/:id', 'user/detail');           // /user/123 -> detail(123)
Route::get('article/:year/:month/:id', 'article/detail'); // 多參數

// 參數類型約束
Route::get('user/:id\d', 'user/detail');         // id 必須數字
Route::get('user/:name\w+', 'user/profile');     // name 單詞字元
Route::get('page/:id\d{4,6}', 'page/view');      // id 4-6 位數字

// 可選參數
Route::get('search/[:keyword]', 'search/index'); // keyword 可選

// 完全匹配 (結尾 $)
Route::get('api/v1/users$', 'api/v1.user/list'); // 不匹配 /api/v1/users/123

// 正則路由 (以 / 開頭結尾)
Route::rule('/^blog\/(\d{4})\/(\d{2})\/(\w+)$/', 'blog/detail?year=:1&month=:2&slug=:3');

// 資源路由 (RESTful 一鍵生成 7 個路由)
Route::resource('posts', 'PostController');
// 生成:
// GET    /posts           -> index
// GET    /posts/create    -> create
// POST   /posts           -> save
// GET    /posts/:id       -> read
// GET    /posts/:id/edit  -> edit
// PUT    /posts/:id       -> update
// DELETE /posts/:id       -> delete

2. 路由分組與中介軟體

<?php
// API 版本分組 + JWT 中介軟體
Route::group('api/v1', function() {
    Route::resource('users', 'UserController');
    Route::resource('posts', 'PostController');
    Route::get('stats', 'StatsController/index');
})->middleware(['jwt.auth', 'rate_limit:100,60']); // 每分鐘 100 次

// 後台管理分組 + RBAC 權限
Route::group('admin', function() {
    Route::get('', 'Index/index');
    Route::resource('users', 'UserController');
    Route::resource('roles', 'RoleController');
})->middleware(['admin.auth', 'permission'])
  ->domain('admin.example.com'); // 域名路由

// 多語言前綴分組
Route::group(':lang', function() {
    Route::get('', 'Index/index');
    Route::get('about', 'Page/about');
})->pattern(['lang' => 'zh|en|ja'])
  ->middleware('locale'); // 中介軟體自動設置語言

3. 域名/子域名路由

<?php
// 綁定模組到子域名
Route::domain('api', 'api');        // api.example.com -> api 模組
Route::domain('admin', 'admin');    // admin.example.com -> admin 模組
Route::domain('shop.*', 'shop');    // shop.example.com, shop.cn -> shop 模組

// 動態子域名 (多租戶)
Route::domain(':tenant.app.example.com', 'tenant')
     ->pattern(['tenant' => '\w+'])
     ->middleware('tenant.resolve'); // 中介軟體解析租戶 ID

4. 路由別名與 URL 生成

<?php
// 定義別名
Route::get('user/profile', 'user/profile')->name('user.profile');

// 控制器/模板生成 URL
url('user/profile', ['id' => 123]);           // /user/profile/id/123
url(':user.profile', ['id' => 123]);          // 使用別名 -> /user/123 (若路由定義為 user/:id)
route('user.profile', ['id' => 123]);         // 同 url()

// 模板中
{:url('user/profile', ['id'=>$user->id])}
{:route('user.profile', ['id'=>$user->id])}

三、偽靜態配置 (REWRITE 模式)

Nginx 配置

server {
    listen 80;
    server_name example.com;
    root /var/www/project/public;
    index index.php index.html;

    location / {
        # 核心:嘗試文件 -> 目錄 -> 重寫到 index.php
        try_files $uri $uri/ /index.php?$query_string;
    }

    location ~ \.php$ {
        fastcgi_pass unix:/run/php/php8.2-fpm.sock;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
        include fastcgi_params;
        fastcgi_buffering off; # 配合流式輸出
    }

    # 靜態資源長期緩存
    location ~* \.(css|js|png|jpg|jpeg|gif|ico|woff2?|svg)$ {
        expires 1y;
        add_header Cache-Control "public, immutable";
    }
}

Apache (.htaccess)

<IfModule mod_rewrite.c>
    Options +FollowSymlinks -Multiviews
    RewriteEngine On
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L]
</IfModule>

四、路由優先級與匹配順序

  1. 靜態路由 (無參數) 優先級最高。
  2. 動態路由 按定義順序匹配,**越複雜/越具體的規則越要放前面**。
  3. 正則路由 最後匹配。
  4. 資源路由 展開為多條靜態/動態路由,按展開順序。

錯誤示範

<?php
// 錯誤:通用規則在前,具體規則永不匹配
Route::get('user/:name', 'user/profile');      // 匹配 user/123
Route::get('user/:id\d', 'user/detail');       // 永遠不會執行

// 正確:具體規則在前
Route::get('user/:id\d', 'user/detail');
Route::get('user/:name', 'user/profile');

五、效能優化建議

優化點建議效果
路由緩存生產環境啟用 php think optimize:route 生成路由映射表路由解析速度提升 10-50 倍
減少正則優先使用參數約束 :id\d 替代正則降低 CPU、避免回溯災難
合併靜態路由大量靜態頁面用單條路由 + 控制器內部判斷減少路由表大小
關閉不必要的轉換'url_convert' => false (若控制器已蛇形命名)省去字串轉換開銷
路由懶加載ThinkPHP 8 支援 Route::lazy() 延遲載入大型路由文件啟動階段記憶體降低

六、常見問題排查

現象可能原因排查步驟
404 Not Found路由未匹配 / Rewrite 未生效1. 檢查 url_route_on 2. 檢查 Nginx try_files 3. 臨時關閉 url_route_must 測試
參數接收不到變量名不匹配 / 類型約束失敗1. 控制器方法參數名與路由變量名一致 2. 檢查約束 \d \w 3. var_dump($this->request->param())
URL 生成錯誤別名衝突 / 參數缺失1. 檢查 route() 參數完整 2. 確認別名唯一 3. 查看生成的 URL 字串
中介軟體不執行中介軟體類不存在 / 註冊順序1. php think middleware:list 確認已註冊 2. 檢查命名空間 3. 中介軟體 handle() 返回 $next($request)

七、遷移建議:從 ThinkPHP 3.2 到 5/6/8

TP 3.2TP 5/6/8說明
'URL_ROUTER_ON' => true'url_route_on' => true配置鍵名統一小寫下劃線
'URL_ROUTE_RULES' => [...]Route::get()/post()/rule()從陣列配置改為代碼定義,支援 IDE 提示
U('User/login')url('user/login')函數名小寫,支援別名
:id\d 在規則字串中Route::get('user/:id\d', ...)語法一致,但現在在代碼中
模組:控制器:方法控制器@方法 或 完整命名空間模組概念弱化,改用命名空間組織

結語

ThinkPHP 路由系統從 3.2 的陣列配置進化為 5/6/8 的流式代碼定義,獲得了類型安全、IDE 支援、中介軟體整合、資源路由、域名路由等現代能力。掌握 路由優先級、參數約束、分組中介軟體、路由緩存、Nginx Rewrite 五大核心,即可構建清晰、高效、可維護的 URL 架構。隨著業務增長,善用 路由懶加載、領域驅動設計 (DDD) 模組劃分、API 版本管理,讓路由層持續服務於業務演進。

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