1. 程式人生 > 其它 >PHP單實現MVC框架路由功能模式

PHP單實現MVC框架路由功能模式

學習程式碼審計時,接觸到mvc框架的路由功能模式,簡單記錄一下。

MVC路由機制

按照傳統,在很多Web框架中(如經典的ASP、JSP、PHP、ASP.NET等之類的框架),URL代表的是磁碟上的物理檔案。
例如,當看到請求http://example.com/albums/list.aspx時,我們可以確定該站點目錄結構中含有一個albums資料夾,並且在該資料夾下還有一個list.aspx檔案。 URL和檔案系統之間這種一一對應的關係並不適用於大部分基於MVC的Web框架,如ASP.NET MVC.一般來說,這些框架採用不同的方法將URL對映到某個類上的方法呼叫,而不是對映到磁碟上的物理檔案。 另外,對於MVC應用程式,URL 請求到達的第一個元件是控制器而不是檢視,而控制器是沒有物理路徑的。

路由機制概述

1.匹配傳入的請求(該請求不匹配伺服器檔案系統中檔案),並將這些請求對映到控制器操作(Controller中的action方法)
MVC基本的處理流程:來了一個URL請求, 從中找到Controller和Action的值, 將請求傳遞給Controller處理. Controller獲取Model資料物件, 並且將Model傳遞給View, 最後View負責呈現頁面。(說白了,就是來了一個URL,找到一個控制器中的方法)(路由是模式,有引數,通過URL中的引數,就可以對應找到符合這種路由模式的方法)

Routing的作用:
´URL: localhost/home/index
´localhost是域名, 所以首先要去掉域名部分: home/index
´對應了上面程式碼中的這種URL結構: {controller}/{action}/{id}
´因為我們建立了這種URL結構的識別規則, 所以能夠識別出 Controller是home, action是index, id沒有則為預設值"".
路由機制一般是由路由名稱,路由模式和預設值構成的
Defaults屬性
最一般的路由情況
routes.MapRoute(
name: "Default",
url: "{controller}/{action}/{id}",
defaults: new { controller = "Home", action = "GlobalIndex", id = UrlParameter.Optional }
);
MVC 模擬路由機制搭建

1、首先,建立好MVC檔案結構


下面我們就來動手試試,怎麼才能訪問到controllers裡面的檔案。

在index.php裡面輸入以下內容:

<?php
/**
* MVC路由功能簡單實現
* @desc 簡單實現MVC路由功能
* $Author: Zhihua_W
*/


//打印出所有的伺服器變數
print_r($_SERVER);

?>
然後輸入訪問地址試試。這裡我是用本地環境的,我訪問的地址是:localhost/MVC/index.php/class/function/var1。下面我貼出兩個最重要的變數:

[REQUEST_URI] => /MVC/index.php/class/function/var1
[SCRIPT_NAME] => /MVC/index.php
其實路由最基本的原理就在這裡,通過這2個變數來提取url地址裡的class名稱和 function名稱,引數等,然後把class include進來,通過PHP的回撥函式 call_user_func_array 呼叫對應的function和傳遞相應的引數。接下來就是各個檔案的具體程式碼了,讀程式碼應該比我寫的易懂。

2、index.php檔案內容

<?php
/**
* MVC路由功能簡單實現
* @desc 簡單實現MVC路由功能
* $Author: Zhihua_W
*/

//定義application路徑
define('APPPATH', trim(__DIR__ . '/'));

//獲得請求地址
$root = $_SERVER['SCRIPT_NAME'];
$request = $_SERVER['REQUEST_URI'];

$URI = array();

//獲得index.php 後面的地址
$url = trim(str_replace($root, '', $request), '/');

//如果為空,則是訪問根地址
if (empty($url)) {
//預設控制器和預設方法
$class = 'index';
$func = 'welcome';
} else {
$URI = explode('/', $url);

//如果function為空 則預設訪問index
if (count($URI) < 2) {
$class = $URI[0];
$func = 'index';
} else {
$class = $URI[0];
$func = $URI[1];
}
}

//把class載入進來
include(APPPATH . '/' . 'application/controllers /' . $class . '.php');

//例項化->將控制器首字母大寫
$obj = ucfirst($class);

call_user_func_array(
//呼叫內部function
array($obj, $func),
//傳遞引數
array_slice($URI, 2)
);
?>
3、在application/controllers裡面新增下面2個檔案(index.php,hello.php)

① index.php

<?php

/**
* MVC路由功能簡單實現
* @desc 簡單實現MVC路由功能
* $Author: Zhihua_W
*/
class Index
{

function welcome()
{
# code...
echo "default covtroller!";
}
}


?>
② hello.php

<?php

/**
* MVC路由功能簡單實現
* @desc 簡單實現MVC路由功能
* $Author: Zhihua_W
*/

class Hello{

public function index(){
echo "hello world!";
}

public function name($name){
echo "hello ".$name;
}
}

?>
4、測試
分別訪問localhost/index.php/Hello/index

localhost/index.php/Hello/name/tom