09.22 MVC 框架中的路由器(Router)是如何跑起來的

MVC 路由器(Router)或分發器(Dispatcher)會檢測 HTTP 請求的 URL,並嘗試將單個 URL 組件與控制器和控制器中定義的方法匹配,同時將所有參數傳入方法中。

下面給出了一個簡單的路由器類,可以大致闡明路由器是如何工作的。然而在實際項目中,路由器要比下面的示例路由器複雜很多,因為它必須處理更多的東西。

class SimpleRouter

{

// 路由數組,存儲我們定義的路由

private $routes;

// 這個方法用於將定義的路由加入到 $routes 數組

function add_route($route, callback $closure)

{

$this->routes[$route] = $closure;

}

// 執行特定的路由

function execute()

{

$path = $_SERVER['PATH_INFO'];

/**

* 檢測給定路由是否被定義,

* 或者執行默認的 '/' 首頁路由。

*/

if (array_key_exists($path, $this->route)) {

$this->route[$path]();

} else {

$this->route['/]();

}

}

}

SimpleRouter 類是 MVC 路由器的簡化模型。它的主要功能是將用戶定義的每個路由添加到數組中,並執行它。要理解它是如何工作的,請將下面的代碼複製到 index.php 文件中。

// index.php

class SimpleRouter

{

// 路由數組,存儲我們定義的路由

private $routes;

// 這個方法用於將定義的路由加入到 $routes 數組

function add_route($route, callback $closure)

{

$this->routes[$route] = $closure;

}

// 執行特定的路由

function execute()

{

$path = $_SERVER['PATH_INFO'];

/**

* 檢測給定路由是否被定義,

* 或者執行默認的 '/' 首頁路由。

*/

if (array_key_exists($path, $this->route)) {

$this->route[$path]();

} else {

$this->route['/]();

}

}

}

/* 創建 Router 實例 */

$router = new SimpleRouter();

/* 添加首頁閉包值路由器 */

$router->add_route('/', function(){

echo 'Hello World';

});

/* 添加另一個閉包路由 */

$router->add_route('/greetings', function(){

echo 'Greetings, my fellow men.';

});

/* 添加可回調函數作為路由 */

$router->add_route('/callback', 'myFunction');

/* 回調函數處理程序 */

function myFunction(){

echo "This is a callback function named '" . __FUNCTION__ ."'";

}

/* 執行路由 */

$router->execute();

現在到瀏覽器訪問下列 url:

http://localhost/index.php/

http://localhost/index.php/greetings

http://localhost/index.php/callback

對於每個 url,你應該會看到在我們的路由中定義的不同消息。那麼路由器是如何工作的呢?

在我們的示例中,add_route 方法將 url 的路徑名(route)添加到路由數組,並且定義對應的處理操作。這個處理操作可以是一個簡單的函數或者回調函數,作為閉包傳入。現在當我們執行路由器的 execute 方法時,它會檢測在當前 routes 數組中是否匹配到路由,如果有,則執行這個函數或回調函數。

如果你使用 var_dump 這個 $routes 數組,你可以看到數組的具體內容。對於每個定義的路由都存儲一個閉包與其關聯。

array (size=3)

'/' =>

object(Closure)[2]

'/greetings' =>

object(Closure)[3]

'/callback' => string 'myFunction' (length=10)

執行處理由以下幾行完成。變量$this->routes[$path] 語句返回一個閉包,該閉包保存在 \\$routes 數組中,用於指定路由的執行,注意語句結尾處的 ()。

$this->routes[$path]();

// 或

$this->routes['/']();

上面的示例簡單地演示了路由器的工作原理,為了簡單起見,我們沒有處理任何錯誤,也沒有考慮路由的安全性問題。


分享到:


相關文章: