PHP的MVC模式實現原理分析(一相簡單的MVC架構範例)_php執行個體

來源:互聯網
上載者:User

他們的工作原理大家應該也比較感興趣,下面我說說一個mvc架構長什麼樣。

路由機制

在互連網我們都是通過url提供服務,因此不同的url有不同的服務。使用者訪問不同的頁面也就獲得了不同的服務。那麼我們的服務是如何通過url來區分不同的服務呢。

我們的web程式就要通過url尋找到不同的檔案,進行不同的商務邏輯處理。我們的路由機制就是根據url,尋找到對應的controller,和action,然後由action進行具體的商務邏輯處理。

一個簡單的controller

複製代碼 代碼如下:

//定義一個controller
class UserControler extends Controller{
     //定義一個action方法,注意一定是public的
     public function index(){
          // do business code
     }
}

具體的對應規則不同的架構映射不同。以下是CodeIgniter架構的URL路由,它會儘力的嘗試各種的可能,來分析URL的情況。

檔案路徑/system/core/URI.php

複製代碼 代碼如下:

// 看看是否是從命令列啟動並執行
if (php_sapi_name() == 'cli' or defined('STDIN')){
    $this->_set_uri_string($this->_parse_cli_args());
    return;
}

// 首先嘗試 REQUEST_URI 這個適應大部分的情況
if ($uri = $this->_detect_uri()){
    $this->_set_uri_string($uri);
    return;
}

// 看看PATH_INFO變數是否存在?nginx需要配置
// Note: some servers seem to have trouble with getenv() so we'll test it two ways
$path = (isset($_SERVER['PATH_INFO'])) ? $_SERVER['PATH_INFO'] : @getenv('PATH_INFO');
if (trim($path, '/') != '' && $path != "/".SELF){
    $this->_set_uri_string($path);
    return;
}

// 沒有PATH_INFO,看看 QUERY_STRING?
$path =  (isset($_SERVER['QUERY_STRING'])) ? $_SERVER['QUERY_STRING'] : @getenv('QUERY_STRING');
if (trim($path, '/') != ''){
    $this->_set_uri_string($path);
    return;
}

//嘗試去從 $_GET 擷取資訊
if (is_array($_GET) && count($_GET) == 1 && trim(key($_GET), '/') != ''){
    $this->_set_uri_string(key($_GET));
    return;
}

// 儘力了,放棄了路由
$this->uri_string = '';
return;

通過上面的嘗試,接下來就是如何利用路由機制載入正確的controller了。

Controller載入機制

我們來看看Codeigniter架構是如何載入到controller並且調用action的。

在/system/core/Codeigniter.php中有如下的代碼。Codeigniter在這之前會根據$_SERVER['PATH_INFO]裡面的值來進行賦值(這個都是靠自己的設定的,預設的話CI他會有許多的if分支進行判斷)。

複製代碼 代碼如下:

//大約在250行
include(APPPATH.'controllers/'.$RTR->fetch_directory().$RTR->fetch_class().'.php');

$class  = $RTR->fetch_class();
$method = $RTR->fetch_method();

//大約在308行
$CI = new $class();

//大約在359行
call_user_func_array(array(&$CI, $method), array_slice($URI->rsegments, 2));

就這樣,通過這個就調用到了我們的controller及其方法了,接下來就是編寫自己的商務邏輯代碼了。


視圖view的顯示

當我們的商務邏輯代碼寫完後,就需要頁面的展示了。很多常見的MVC架構在頁面的調用是這麼寫的。

複製代碼 代碼如下:
//controller中action的方法
public function index(){
    // ... 許多的商務邏輯代碼
    $data = array('name'=>'abc', 'age'=>12, .... );
    return $this->render('view/path/file.html',$data);
}

接著在視圖檔案view/path/file.html裡寫上一下代碼。
複製代碼 代碼如下:
<div>
姓名 : <?=$name ?>
年齡 : <?php echo $age; ?>
</div>

這段如何將資料渲染到視圖中,這段代碼以前我一直很好奇,現在我明白了,我們來看看是如何?的。
複製代碼 代碼如下:
protected function render($template, array $var = array() )
{
    extract($var);   // 抽取數組中的變數
    ob_end_clean (); //關閉頂層的輸出緩衝區內容
    ob_start ();     // 開始一個新的緩衝區
    require TEMPLATE_ROOT . $template . '.html';  //載入視圖view
    $content = ob_get_contents ();             // 獲得緩衝區的內容
    ob_end_clean ();           // 關閉緩衝區

    //ob_end_flush();      // 這個是直接輸出緩衝區的內容了,不用再次緩衝起來。
    ob_start();            //開始新的緩衝區,給後面的程式用
    return $content;       // 返迴文本,此處也可以位元組echo出來,並結束代碼。
}

在這短短的幾行代碼中,全都是精華,就是這些非常重要的,全是php的內建函數,接下來我們來具體分析分析。

看看第一個extract($var)。這個函數從數組中將變數匯入到當前的符號表。剛剛就將$data數組裡面的name、age抽取出來,這樣就可以在視圖view中使用$name $age。更詳細的請參考http://www.php.net/manual/zh/function.extract.php

第二個ob_end_clean()的作用是關閉頂層的緩衝區,為了是之前的程式不小心echo出的一些文字給清楚了,為了下一行的重新開闢一塊緩衝區。

第三個ob_start()是開啟一塊新的緩衝區,為了是將視圖的內容放到緩衝區。當然了,緩衝區有一定的大小,如果內容超出了緩衝區的設定值,那麼會自動的發送給server。

第四個require file,這個就是第一個參數,根據自己的規則去載入視圖的檔案。其中檔案裡可以夾雜php、html的代碼。你在這個render()函式宣告的任何局部變數或者這裡能訪問到的任何全域變數,都可以在require的file檔案中訪問到。

第五個$content = ob_get_contents ()很重要,是為了將緩衝區的內容取出來,但不清除它。

第七個ob_start()是重新開啟一個緩衝區,為了是下面的程式需要使用緩衝區。有寫架構可能不用對$content的內容進行操作了,那麼直接ob_end_flush()將緩衝區的內容輸出出來就行了。

這個是一個很簡單的展示視圖的過程。如果直接使用這個不方便對視圖view進行模組化,因此一些架構都不會這麼直接用的。

我們從這個函數也可以看到程式有點類似程式中斷保護現場的感覺。只不過中斷保護現場會先儲存資料,然後在返回的時候恢複回來。這裡只有關閉上一個緩衝區,開啟一個新的緩衝區,關閉這個緩衝哦過去,開啟另外一個緩衝區。

至此,我們看到一個簡單的PHP的MVC架構。如果你有興趣可以自己開發一個MVC架構,或者更深入點的HMVC。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.