天天躁日日躁狠狠躁AV麻豆-天天躁人人躁人人躁狂躁-天天澡夜夜澡人人澡-天天影视香色欲综合网-国产成人女人在线视频观看-国产成人女人视频在线观看

PHP的MVC模式實(shí)現(xiàn)原理分析(一相簡(jiǎn)單的MVC框架范例)

他們的工作原理大家應(yīng)該也比較感興趣,下面我說(shuō)說(shuō)一個(gè)mvc框架長(zhǎng)什么樣。

路由機(jī)制

互聯(lián)網(wǎng)我們都是通過(guò)url提供服務(wù),因此不同的url有不同的服務(wù)。用戶訪問(wèn)不同的頁(yè)面也就獲得了不同的服務(wù)。那么我們的服務(wù)是如何通過(guò)url來(lái)區(qū)分不同的服務(wù)呢。

我們的web程序就要通過(guò)url尋找到不同的文件,進(jìn)行不同的業(yè)務(wù)邏輯處理。我們的路由機(jī)制就是根據(jù)url,尋找到對(duì)應(yīng)的controller,和action,然后由action進(jìn)行具體的業(yè)務(wù)邏輯處理。

一個(gè)簡(jiǎn)單的controller

復(fù)制代碼 代碼如下:
//定義一個(gè)controller
class UserControler extends Controller{
     //定義一個(gè)action方法,注意一定是public的
     public function index(){
          // do business code
     }
}

具體的對(duì)應(yīng)規(guī)則不同的框架映射不同。以下是CodeIgniter框架的URL路由,它會(huì)盡力的嘗試各種的可能,來(lái)分析URL的情況。

文件路徑/system/core/URI.php

復(fù)制代碼 代碼如下:
// 看看是否是從命令行運(yùn)行的
if (php_sapi_name() == 'cli' or defined('STDIN')){
    $this->_set_uri_string($this->_parse_cli_args());
    return;
}

// 首先嘗試 REQUEST_URI 這個(gè)適應(yīng)大部分的情況
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;
}

// 沒(méi)有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;

通過(guò)上面的嘗試,接下來(lái)就是如何利用路由機(jī)制加載正確的controller了。

Controller加載機(jī)制

我們來(lái)看看Codeigniter框架是如何加載到controller并且調(diào)用action的。

在/system/core/Codeigniter.php中有如下的代碼。Codeigniter在這之前會(huì)根據(jù)$_SERVER['PATH_INFO]里面的值來(lái)進(jìn)行賦值(這個(gè)都是靠自己的設(shè)定的,默認(rèn)的話CI他會(huì)有許多的if分支進(jìn)行判斷)。
復(fù)制代碼 代碼如下:
//大約在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));

就這樣,通過(guò)這個(gè)就調(diào)用到了我們的controller及其方法了,接下來(lái)就是編寫自己的業(yè)務(wù)邏輯代碼了。


視圖view的顯示

當(dāng)我們的業(yè)務(wù)邏輯代碼寫完后,就需要頁(yè)面的展示了。很多常見(jiàn)的MVC框架在頁(yè)面的調(diào)用是這么寫的。
復(fù)制代碼 代碼如下://controller中action的方法
public function index(){
    // ... 許多的業(yè)務(wù)邏輯代碼
    $data = array('name'=>'abc', 'age'=>12, .... );
    return $this->render('view/path/file.html',$data);
}
接著在視圖文件view/path/file.html里寫上一下代碼。
復(fù)制代碼 代碼如下:<div>
姓名 : <?=$name ?>
年齡 : <?php echo $age; ?>
</div>
這段如何將數(shù)據(jù)渲染到視圖中,這段代碼以前我一直很好奇,現(xiàn)在我明白了,我們來(lái)看看是如何實(shí)現(xiàn)的。
復(fù)制代碼 代碼如下:protected function render($template, array $var = array() )
{
    extract($var);   // 抽取數(shù)組中的變量
    ob_end_clean (); //關(guān)閉頂層的輸出緩沖區(qū)內(nèi)容
    ob_start ();     // 開始一個(gè)新的緩沖區(qū)
    require TEMPLATE_ROOT . $template . '.html';  //加載視圖view
    $content = ob_get_contents ();             // 獲得緩沖區(qū)的內(nèi)容
    ob_end_clean ();           // 關(guān)閉緩沖區(qū)

    //ob_end_flush();      // 這個(gè)是直接輸出緩沖區(qū)的內(nèi)容了,不用再次緩存起來(lái)。
    ob_start();            //開始新的緩沖區(qū),給后面的程序用
    return $content;       // 返回文本,此處也可以字節(jié)echo出來(lái),并結(jié)束代碼。
}

在這短短的幾行代碼中,全都是精華,就是這些非常重要的,全是php的內(nèi)置函數(shù),接下來(lái)我們來(lái)具體分析分析。

看看第一個(gè)extract($var)。這個(gè)函數(shù)從數(shù)組中將變量導(dǎo)入到當(dāng)前的符號(hào)表。剛剛就將$data數(shù)組里面的name、age抽取出來(lái),這樣就可以在視圖view中使用$name $age。更詳細(xì)的請(qǐng)參考http://www.php.NET/manual/zh/function.extract.php

第二個(gè)ob_end_clean()的作用是關(guān)閉頂層的緩沖區(qū),為了是之前的程序不小心echo出的一些文字給清楚了,為了下一行的重新開辟一塊緩沖區(qū)。

第三個(gè)ob_start()是開啟一塊新的緩沖區(qū),為了是將視圖的內(nèi)容放到緩沖區(qū)。當(dāng)然了,緩沖區(qū)有一定的大小,如果內(nèi)容超出了緩沖區(qū)的設(shè)定值,那么會(huì)自動(dòng)的發(fā)送給server。

第四個(gè)require file,這個(gè)就是第一個(gè)參數(shù),根據(jù)自己的規(guī)則去加載視圖的文件。其中文件里可以?shī)A雜php、html的代碼。你在這個(gè)render()函數(shù)聲明的任何局部變量或者這里能訪問(wèn)到的任何全局變量,都可以在require的file文件中訪問(wèn)到。

第五個(gè)$content = ob_get_contents ()很重要,是為了將緩沖區(qū)的內(nèi)容取出來(lái),但不清除它。

第七個(gè)ob_start()是重新開啟一個(gè)緩沖區(qū),為了是下面的程序需要使用緩沖區(qū)。有寫框架可能不用對(duì)$content的內(nèi)容進(jìn)行操作了,那么直接ob_end_flush()將緩沖區(qū)的內(nèi)容輸出出來(lái)就行了。

這個(gè)是一個(gè)很簡(jiǎn)單的展示視圖的過(guò)程。如果直接使用這個(gè)不方便對(duì)視圖view進(jìn)行模塊化,因此一些框架都不會(huì)這么直接用的。

我們從這個(gè)函數(shù)也可以看到程序有點(diǎn)類似程序中斷保護(hù)現(xiàn)場(chǎng)的感覺(jué)。只不過(guò)中斷保護(hù)現(xiàn)場(chǎng)會(huì)先保存數(shù)據(jù),然后在返回的時(shí)候恢復(fù)回來(lái)。這里只有關(guān)閉上一個(gè)緩沖區(qū),開啟一個(gè)新的緩沖區(qū),關(guān)閉這個(gè)緩沖哦過(guò)去,開啟另外一個(gè)緩沖區(qū)。

至此,我們看到一個(gè)簡(jiǎn)單的php的MVC框架。如果你有興趣可以自己開發(fā)一個(gè)MVC框架,或者更深入點(diǎn)的HMVC。

php技術(shù)PHP的MVC模式實(shí)現(xiàn)原理分析(一相簡(jiǎn)單的MVC框架范例),轉(zhuǎn)載需保留來(lái)源!

鄭重聲明:本文版權(quán)歸原作者所有,轉(zhuǎn)載文章僅為傳播更多信息之目的,如作者信息標(biāo)記有誤,請(qǐng)第一時(shí)間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 色情内射少妇兽交 | 一品道门免费视频韩国 | 95国产精品人妻无码久 | 久久精品123| 人成片在线观看亚洲无遮拦 | 99视频这里只有精品 | 亚洲精品www久久久久久 | 麻豆精品传媒一二三区 | 男女高潮又爽又黄又无遮挡 | 忘忧草日本在线WWW日本 | 两性午夜刺激爽爽视频 | 美女裸露100%奶头视频 | 国产亚洲精品a在线观看app | 瑜伽牲交AV | 美女脱了内裤张开腿让男人桶到爽 | 快播黄色电影 | 玩弄朋友娇妻呻吟交换电影 | 亚洲AV无码专区国产精品99 | 亚洲精品久久久无码一区二区 | 网址在线观看你懂我意思吧免费的 | 亚洲AV精品无码国产一区 | 日本漫画母亲口工子全彩 | 国产亚洲精品久久77777 | 亚州免费一级毛片 | 久久精品国产亚洲AV麻豆欧美玲 | 国产在线精品一区二区在线看 | 秋霞电影网午夜鲁丝片 | 色多多污污在线播放免费 | 亚洲免费观看在线视频 | 中文字幕欧美一区 | 大香网伊人久久综合网2020 | 全黄H全肉禁乱公 | 中文字幕在线视频在线看 | 狠狠色狠狠色综合曰曰 | 成人无码精品一区二区在线观看 | 国产免费久久爱久久啪 | 亚洲一日韩欧美中文字幕在线 | 18禁裸乳无遮挡免费网站 | 24小时日本在线电影 | 欧美激情性AAAAA片欧美 | 欧美手机在线 |