DIY 實現 ThinkPHP 核心框架 (三)路由

cn-five發表於2020-08-26

框架路由的兩種方式

在框架中,有兩種方式將請求資訊分發到具體的控制器。第一種是在入口檔案 index.php 後面新增“/模組/控制器/操作”。這種方式使得 URL 顯得過於累贅,並且限制了 URL 的格式,不能隨意自定義。另一種是通過定義路由規則對 URL 進行匹配,找到相應的模組、控制器和操作。

路由的實現原理

ThinkPHP 中,框架會自動識別 URL 中的模組、控制器和操作,無需開發人員專門定義路由規則。

隱藏入口檔案

URL http://diy.tp/index.php/employee/employee/index 過長,希望換成一個簡化地址 http://diy.tp/index
Nginx 配置檔案中的 server 段新增

location / {
            root           /root/web/mytp/public;
            index  index.html index.htm index.php;
            # $request_filename 表示請求引數 也就是 diy.tp/ 之後的部分
            # 例如 diy.tp/index $request_filename 就是 index
            # !-e 表示不存在
            if (!-e $request_filename) {
                # ^(.*)$ 表示請求路徑 比如 index
                # $1 表示引用 ^(.*)$
                # 也就是說如果 index 不存在
                # 重寫為 /index.php/ 開頭的 URL diy.tp/index.php/index
                # last 的狀態碼是 301 表示跳轉至重寫的 URL
                rewrite ^(.*)$ /index.php/$1 last;
                break;
            }
        }

/home/web/mytp 目錄建立 application 目錄,將 public/employee 目錄放入 application 目錄中。

application
    └── employee
        ├── controller
        │   └── EmployeeController.php
        ├── model
        │   └── EmployeeModel.php
        └── view
            └── employee.html

public 目錄只有入口檔案 index.php 提供對外訪問,目錄安全性高,耦合低,不影響重寫。

定義路由規則

更改 index.php

$pathinfo =  !empty($_SERVER['PATH_INFO']) ? $_SERVER['PATH_INFO'] : '';

// 定義路由規則
$route = [
    'index' => '/employee/employee/index',
];

$pathinfo = trim($pathinfo, '/');
$pathinfo = $route[$pathinfo] ?? '';
$arr = explode('/', trim($pathinfo, '/'));

if (!isset($arr[2])) {
    exit('該操作不存在!');
}

list ($module, $controller, $action) = $arr;
// 目錄改變 需從上一級目錄進入 application
define('MODULE_PATH', '../application/' . $module . '/');

$controllerName = ucwords($controller) . 'Controller';
$controllerPath = MODULE_PATH . 'controller/' . $controllerName . '.php';
require $controllerPath;

$empolyee = new $controllerName();
$empolyee->$action();

測試 diy.tp/index

本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章