




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
1、關(guān)于php MVCl 什么是MVC?簡單的說就是將網(wǎng)站源碼分類、分層。MVC三個(gè)字母的含義:M:Model 模型,負(fù)責(zé)數(shù)據(jù)庫操作。V:View 視圖,負(fù)責(zé)調(diào)用Model調(diào)取數(shù)據(jù),再調(diào)用模板,展示出最終效果。C:Controller 控制器,程序的入口,決定該調(diào)用哪個(gè)View,并告訴View該做什么。如此說來,程序的執(zhí)行順序是C-V-M 或 C-M ,和MVC的名字正好相反。l 為什么要MVC?1. 能使網(wǎng)站程序物理結(jié)構(gòu)更合理。當(dāng)用PHP建設(shè)一個(gè)網(wǎng)站的時(shí)候,最笨的方法,你可能把每個(gè)頁面建成一個(gè)PHP文件。如果你的網(wǎng)站只有index.php,menu.php.article.php 三個(gè)頁面,那你
2、可以不用MVC,但我們做一般的網(wǎng)站的時(shí)候,動(dòng)輒幾十個(gè)頁面,把所有頁面放在根目錄顯然不是我們所能接受的,于是你需要一個(gè)合理的思想去將你的代碼分類,按功能把他們分成不同的目錄,且由程序智能的載入調(diào)用,這就是MVC要幫助你做的。2. 使代碼更容易維護(hù)。我們?cè)賮砜磫蝹€(gè)頁面,最笨的方法,就是PHP代碼與HTML代碼混合,這顯然不夠好,你在維護(hù)網(wǎng)站的時(shí)候不得不區(qū)分哪里是PHP,哪里是HTML,這對(duì)于一個(gè)程序員來說,簡直只災(zāi)難。于是很多人就使用Smarty,這樣就可以將“數(shù)據(jù)處理”與“頁面展示”分開來,這樣做的確不錯(cuò),也有很多人正在這么做,但這還不是MVC,MVC要做的就是將“數(shù)據(jù)處理”再分為“邏輯處理”與
3、“數(shù)據(jù)庫操作”,這就是所說的分層。這樣當(dāng)你的程序錯(cuò)誤或想要修改的時(shí)候,就變得很輕松了,當(dāng)頁面顯示錯(cuò)誤的時(shí)候,你就去檢查V或模板文件;當(dāng)邏輯有問題的時(shí)候,你就去檢查C和V;當(dāng)你數(shù)據(jù)庫操作錯(cuò)誤就去檢查M。其實(shí)MVC一般要把PHP的一個(gè)頁面分割為4個(gè)頁面,分別是C,V,M,模板。各司其職,方便管理。3. 有利于代碼復(fù)用。MVC會(huì)把一般會(huì)把一個(gè)大的功能放在一個(gè)目錄下,也就是由一個(gè)C去管理。例如要做一個(gè)含有會(huì)員系統(tǒng)的網(wǎng)站,我們就可以把會(huì)員相關(guān)的代碼都放到user目錄里,由User_Controller統(tǒng)一管理,當(dāng)我們另一個(gè)網(wǎng)站也需要會(huì)員系統(tǒng)的時(shí)候,我們就可以直接把這個(gè)目錄復(fù)制過去,修改一下接口就可以了。
4、l PHP如何實(shí)現(xiàn)MVC?我們需要三個(gè)基類:Controller、View、Model ,然后不同的C、V、M分別繼承他們就有對(duì)應(yīng)的屬性與方法了,如果這里你不理解,可以去看看面向?qū)ο蟮臅?。我給大家提供一種MVC基類的設(shè)計(jì)思路,僅供參考:1. Controller類的設(shè)計(jì)(C)一個(gè)main()方法,供程序調(diào)用,主要是通過get和post變量決定該如何處理。一個(gè)getModel($model)方法,在需要調(diào)用數(shù)據(jù)庫的時(shí)候,調(diào)用對(duì)應(yīng)目錄的M。一個(gè)display($view)方法,在main()方法中調(diào)用,載入對(duì)應(yīng)的V,并調(diào)用V的main()方法;2. View類的設(shè)計(jì)與Controller很相似(V
5、)一個(gè)main()方法,當(dāng)C載入V的時(shí)候調(diào)用這個(gè)方法,使程序能繼續(xù)執(zhí)行下去。一個(gè)getModel($model)方法,在需要調(diào)用數(shù)據(jù)庫的時(shí)候,調(diào)用對(duì)應(yīng)目錄的M。一個(gè)display($template),調(diào)用對(duì)應(yīng)的模板文件,并把數(shù)據(jù)傳遞給模板。3. Model類的設(shè)計(jì)(M)可以定義一些屬性,例如要操作那些表,操作那些字段等。一個(gè)getDB()方法,獲得一個(gè)數(shù)據(jù)庫類的實(shí)例,(數(shù)據(jù)庫類一般都是用單件模式設(shè)計(jì)的)一個(gè)load()方法,載入一個(gè)數(shù)據(jù)。一個(gè)add()方法,可以根據(jù)定義好的屬性自動(dòng)構(gòu)造SQL語句,并執(zhí)行插入操作。一個(gè)eidt()方法,同上,但執(zhí)行修改操作。一個(gè)del()方法,同上,但執(zhí)行刪除
6、操作。l MVC是如何工作的?為了能使新手更好的理解我這個(gè)思路的工作原理,我們現(xiàn)在模擬一個(gè)用戶登錄的場景?,F(xiàn)在假設(shè),所有的數(shù)據(jù)都提交給index.php,第一步:我們提交各get變量,告訴index.php該用哪個(gè)C,例如可以這樣index.php?controller=user然后index接收到get變量,什么也不需要做,直接找到/user/controller.php,把所有數(shù)據(jù)丟給他,本來GET和POST就是全局的,所以index.php也不需要做什么,直接調(diào)用C的main函數(shù)就可以了,到此index.php的任務(wù)完成。第二步:C的main函數(shù)開始執(zhí)行,檢查變量,發(fā)現(xiàn)用戶要執(zhí)行的登錄操
7、作(很簡單,你post個(gè)變量do=login就可以了),于是調(diào)用getModel,載入對(duì)應(yīng)的M類(例如/user/models/model.php),并實(shí)例化, 調(diào)用實(shí)例的load方法,載入該用戶的數(shù)據(jù)資料,判斷是否與用戶提交的密碼一致,如果提交的數(shù)據(jù)不正確header跳轉(zhuǎn)到出錯(cuò)頁面,如果正確,調(diào)用display()方法,載入對(duì)應(yīng)的V(例如/user/views/details.php),并實(shí)例化,調(diào)用其main()函數(shù),進(jìn)入第三步。到此C的任務(wù)已完成,第二步操作均在main函數(shù)中進(jìn)行。第三步:你可以選擇調(diào)用getModel()載入M,重寫調(diào)取數(shù)據(jù),也可以在C實(shí)例化V的時(shí)候,把參數(shù)傳過來(例如
8、SESSION),當(dāng)V已經(jīng)確定得到數(shù)據(jù)以后,display(),載入模板,MVC執(zhí)行完畢。當(dāng)然,由于字?jǐn)?shù)與精力限制,這里寫的只是非常簡要的概括,實(shí)際實(shí)施的時(shí)候要考慮很多細(xì)節(jié),但我設(shè)計(jì)MVC的時(shí)候,大概思路就是這樣,也用到了實(shí)際中,感覺良好。簡單的php MVC今天研究了下PHP MVC結(jié)構(gòu),所以決定自己寫個(gè)簡單的MVC,以待以后有空再豐富。至于什么MVC結(jié)構(gòu),其實(shí)就是三個(gè)Model,Contraller,View單詞的簡稱,,Model,主要任務(wù)就是把數(shù)據(jù)庫或者其他文件系統(tǒng)的數(shù)據(jù)按 照我們需要的方式讀取出來。View,主要負(fù)責(zé)頁面的,把數(shù)據(jù)以html的形式顯示給用戶。Controller,主要
9、負(fù)責(zé)業(yè)務(wù)邏輯,根據(jù)用戶的 Request進(jìn)行請(qǐng)求的分配,比如說顯示登陸界面,就需要調(diào)用一個(gè)控制器userController的方法loginAction來顯示。下面我們用PHP來創(chuàng)建一個(gè)簡單的MVC結(jié)構(gòu)系統(tǒng)。首先創(chuàng)建單點(diǎn)入口,即bootstrap文件index.php,作為整個(gè)MVC系統(tǒng)的唯一入口。什么是單點(diǎn)入口呢?所謂單點(diǎn)入口就是整個(gè)應(yīng)用程序只有一 個(gè)入口,所有的實(shí)現(xiàn)都通過這個(gè)入口來轉(zhuǎn)發(fā)。為什么要做到單點(diǎn)入口呢?單點(diǎn)入口有幾大好處:第一、一些系統(tǒng)全局處理的變量,類,方法都可以在這里進(jìn)行處理。 比如說你要對(duì)數(shù)據(jù)進(jìn)行初步的過濾,你要模擬session處理,你要定義一些全局變量,甚至你要注冊(cè)一些對(duì)
10、象或者變量到注冊(cè)器里面。第二、程序的架構(gòu)更加 清晰明了。當(dāng)然好處還有很多的。1. <?php2. include("core/ini.php");3. initializer:initialize();4. $router = loader:load("router");5. dispatcher:dispatch($router);這個(gè)文件就只有4句,我們現(xiàn)在一句句來分析。include(”core/ini.php”);我們來看core/ini.php1. <?php2. set_include_path(get_include_path(
11、) . PATH_SEPARATOR . "core/main");3. /set_include_path Sets the include_path configuration option4. function _autoload($object)5. require_once("$object.php");6. 這個(gè)文件首先設(shè)置了include_path,也就是我們?nèi)绻野奈募嬖V系統(tǒng)在這個(gè)目錄下查找。其實(shí)我們定義_autoload()方法,這個(gè)方法是在PHP5增加的,就是當(dāng)我們實(shí)例化一個(gè)函數(shù)的時(shí)候,如果本文件沒有,就會(huì)自動(dòng)去加載文件。接
12、下來我們看下面一句initializer:initialize();這就話就是調(diào)用initializer類的一個(gè)靜態(tài)函數(shù)initialize,因?yàn)槲覀冊(cè)趇ni.php,設(shè)置了include_path,以及定義了_autoload,所以程序會(huì)自動(dòng)在core/main目錄查找initializer.php.initializer.php文件如下:1. <?php2. class initializer3. 4. public static function initialize()5. set_include_path(get_include_path().PATH_SEPARATOR .
13、"core/main");6. set_include_path(get_include_path().PATH_SEPARATOR . "core/main/cache");7. set_include_path(get_include_path().PATH_SEPARATOR . "core/helpers");8. set_include_path(get_include_path().PATH_SEPARATOR . "core/libraries");9. set_include_path(get_in
14、clude_path().PATH_SEPARATOR . "app/controllers");10. set_include_path(get_include_path().PATH_SEPARATOR."app/models");11. set_include_path(get_include_path().PATH_SEPARATOR."app/views");12. /include_once("core/config/config.php");13. 14. 15. ?>這個(gè)函數(shù)很簡單,就只定義了
15、一個(gè)靜態(tài)函數(shù),initialize函數(shù),這個(gè)函數(shù)就是設(shè)置include_path,這樣,以后如果包含文件,或者_(dá)autoload,就會(huì)去這些目錄下查找。OK,我們繼續(xù),看第三句$router = loader:load(”router”);這句話也很簡單,就是加載loader函數(shù)的靜態(tài)函數(shù)load,下面我們來loader.php1. <?php2. class loader3. 4. private static $loaded = array();5. public static function load($object)6. $valid = array( "librar
16、y", "view", "model","helper", "router", "config","hook","cache","db");7. if (!in_array($object,$valid)8. throw new Exception("Not a valid object '$object' to load");9. 10. if (empty(self:$loaded$ob
17、ject)11. self:$loaded$object= new $object();12. 13. return self:$loaded$object;14. 15. 這個(gè)文件就是去加載對(duì)象,因?yàn)橐院笪覀兛赡軙?huì)豐富這個(gè)MVC系統(tǒng),會(huì)有model,helper,config等等的組件。如果加載的組件不在有效 的范圍內(nèi),我們拋出一個(gè)異常。如果在的話,我們實(shí)例化一個(gè)對(duì)象,其實(shí)這里用了單件設(shè)計(jì)模式。也就是這個(gè)對(duì)象其實(shí)就只能是一個(gè)實(shí)例化對(duì)象,如果沒有實(shí)例化, 創(chuàng)建一個(gè),如果存在的,則不實(shí)例化。好,因?yàn)槲覀儸F(xiàn)在要加載的是router組件,所以我們看下router.php文件,這個(gè)文件的作用就是映射U
18、RL,對(duì)URL進(jìn)行解析。router.php1. <?php2. class router3. 4. private $route;5. private $controller;6. private $action;7. private $params;8. public function _construct()9. / 例如果URL為:,那么array_keys($_GET)的值為Array ( 0 => a 1 => p ),$_GET的值為Array ( a => good p => 12 ),arrary_keys(array $array)以數(shù)組的形式
19、返回$array中的鍵。10. $path = array_keys($_GET);11. if (!isset($path0)/判斷是否取得了$_GET,即用戶是否提交了$_GET變量,如果沒有則12. if (!empty($default_controller)/如果有默認(rèn)的控制器13. $path0 = $default_controller;/則設(shè)置默認(rèn)控制器14. else15. $path0 = "index"/否則以index為默認(rèn)控制器16. /能夠取得用戶提交的$_GET變量的話17. $route= $path0;$this->route = $
20、route;/spilt(string $string1,str $string2)函數(shù)用$string1為分割符將$string2分割成數(shù)組返回,比如spilt(“/”,”model/action/param”)將返回array(0=>model1=>action2=>param)。(比如我們的地址是 $routeParts0=user,$routeParts1=profile,$routeParts2=id,$routeParts3=3,)18. $routeParts = split( "/",$route);/split();可以換為更高效的exp
21、lode(string $str1,string $str2)函數(shù)使用(用$str1將$str2分割到數(shù)組中),此處split( "/",$route)換為explode( "/",$route)效果相同,但后者更高效。19. $this->controller=$routeParts0;/取得控制器部分20. $this->action=isset($routeParts1)? $routeParts1:"base"/取得動(dòng)作(操作)/array_shift(array $array) 將 $array 的第一個(gè)單元移出
22、并作為結(jié)果返回 ,將 array 的長度減一并將所有其它單元向前移動(dòng)一位。所有的數(shù)字鍵名將改為從零開始計(jì)數(shù),文字鍵名將不變。如果 array 為空(或者不是數(shù)組),則返回 NULL。/通過以下21、22、23代碼,控制器所需參數(shù)部分就能取到,比如18行上方的舉例,經(jīng)過21后$routeParts0=profileprofile,$routePartsy減少為3個(gè)元素,經(jīng)過22后$routeParts0=id,$routeParts1=3,減少為2個(gè)元素,這樣23行中的$this->params就是具有2個(gè)元素的數(shù)組$this->params0 =id ,$this->para
23、ms1=321. array_shift($routeParts);/把控制器部分內(nèi)容去掉22. array_shift($routeParts);/把動(dòng)作部分內(nèi)容去掉23. $this->params=$routeParts;/只保留參數(shù)用以后部分24. 25. public function getAction() 26. if (empty($this->action) $this->action="main"/如果沒有動(dòng)作,則把”main”作為默認(rèn)動(dòng)作27. return $this->action;28. 29. public functi
24、on getController() 30. return $this->controller;31. 32. public function getParams() 33. return $this->params;34. 35. 我們可以看到,首先我們是拿到$_GET,用戶Request的URL,然后從URL里我們解析出Controller和Action,以及Paramsindeindex.php?user/profile/id/3那么從上面的地址,我們可以拿到controller是user,action是profile,參數(shù)是id以及3OK我們看最后一句,就是dispatch
25、er:dispatch($router);這句話的意思很明了,就是拿到URL解析的結(jié)果,然后通過dispatcher來分發(fā)controlloer及action來Response(回應(yīng))給用戶好,我們來看下dispatcher.php文件1. <?2. class dispatcher3. 4. public static function dispatch($router)5. 6. global $app;7. ob_start();8. $start = microtime(true);/取得腳本開始運(yùn)行時(shí)間9. $controller = $router->getContro
26、ller();10. $action = $router->getAction();11. $params = $router->getParams();12. $controllerfile = "app/controllers/$controller.php"/生成控制器文件名13. if (file_exists($controllerfile)/如果該控制器文件存在就加載,并且實(shí)例化該控制器到$app,否則拋出異常(第25行)14. require_once($controllerfile);15. $app = new $controller();16
27、. $app->setParams($params);/該控制器設(shè)置自身需要的參數(shù)17. $app->$action();/控制器開始監(jiān)聽,接受用戶行為18. if (isset($start) /如果已經(jīng)設(shè)置了腳本開始時(shí)間19. echo "20. Tota1l time for dispatching is : ".(microtime(true)-$start)." seconds.21. "22. $output = ob_get_clean();23. echo $output;24. else25. throw new Excep
28、tion("Controller not found");26. 27. 28. 這個(gè)類很明顯,就是拿到$router來,尋找文件中的controller和action來回應(yīng)用戶的請(qǐng)求。OK,我們一個(gè)簡單的,MVC結(jié)構(gòu),就這樣好了,當(dāng)然這里還不能算是一個(gè)很完整的MVC,因?yàn)檫@里還沒有涉及到View和Model,有空我再這里豐富。我們來寫個(gè)Controller文件來測試下上面的這個(gè)系統(tǒng)。我們?cè)赼pp/controllers/下創(chuàng)建一個(gè)user.php文件/user.php1. <?php2. class user3. 4. function base()5. 6. pu
29、blic function login()7. 8. echo 'login html page'9. 10. public function register()11. 12. echo 'register html page'13. 14. public function setParams($params)15. var_dump($params);16. 17. 然后你可以在瀏覽器中輸入http:/localhost/index.php?user/register 或者 http:/localhost/index.php?user/login來測試下。另
30、外一篇php MVC模式介紹先來說一下程序的執(zhí)行流程 首先有個(gè)入口文件, 然后初始化一些程序, 之后根據(jù)請(qǐng)求調(diào)用不同的類和方法 首先我們弄一個(gè)入口文件 Index.php 來看看代碼 1. <?php 2. require "Init.php" 3. $control = new Controller(); 4. $control->Run(); 5. ?> 代碼沒什么特別的, 首先先引入Init.php文件 然后實(shí)例化一個(gè)(控制器)類 然后調(diào)用該類的Run()方法 這里我們把這個(gè)類叫做控制器 既然引入了Init.php文件, 那么我們繼續(xù)看看Init.p
31、hp文件的源碼 1. <?php 2. header("Content-type:text/html;charset=utf-8"); 3. !defined('ROOT_PATH') && define('ROOT_PATH', str_replace('', '/', dirname(_FILE_); 4. require ROOT_PATH . '/Core/Config.php' /引入配置文件 5. require ROOT_PATH . '/Core/C
32、ontroller.class.php' /引入控制器類文件 6. require ROOT_PATH . '/Core/View.class.php' /視圖類文件 7. require ROOT_PATH . '/Core/Model.class.php' /模型類文件 8. ?> 分析一下代碼, 如果你懂了, 可以略過這一步, 繼續(xù)往下看哦. 首先設(shè)置字符集, 然后判斷如果沒有定義常量"ROOT_PATH"那么就定義它 然后就是引入一些文件, 首先是配置文件, 控制器類文件, 視圖類文件, 模型類文件 同理既然引入了文件,
33、那么我們就打開文件看看代碼, 先來看Config.php文件 1. <?php 2. $C = array( 3. 'URL_MODE' => 1, /URL模式, 1普通模式, 2 PATH_INFO模式 4. 'DEFAULT_CONTROL' => 'welcome', /默認(rèn)調(diào)用的控制器 5. 'DEFAULT_ACTION' => 'index', /默認(rèn)執(zhí)行的方法 6. ); 7. ?> 沒什么特別的就是一個(gè)數(shù)組, 有三個(gè)值, 暫時(shí)先這樣, 以后有需要可以再增加。 那么好,
34、 我們繼續(xù)看Controll.class.php <?php class Controller public function Run() $this->Analysis(); /開始解析URL獲得請(qǐng)求的控制器和方法 $control = $_GET'c' $action = $_GET'a' /這里構(gòu)造出控制器文件的路徑 $controlFile = ROOT_PATH . '/Controllers/' . $control . '.class.php' if(!file_exists($controlFile)
35、/如果文件不存在提示錯(cuò)誤, 否則引入 exit('控制器不存在' . $controlFile); include($controlFile); $class = ucwords($control); /將控制器名稱中的每個(gè)單詞首字母大寫,來當(dāng)作控制器的類名 if(!class_exists($class) /判斷類是否存在, 如果不存在提示錯(cuò)誤 exit('未定義的控制器類' . $class); $instance = new $class(); /否則創(chuàng)建實(shí)例 if(!method_exists($instance, $action) /判斷實(shí)例$inst
36、ance中是否存在$action方法, 不存在則提示錯(cuò)誤 exit('不存在的方法' . $action); $instance->$action(); /* * 解析URL獲得控制器與方法 * * access protected * return void */ protected function Analysis() global $C; /包含全局配置數(shù)組, 這個(gè)數(shù)組是在Config.php文件中定義的 if($C'URL_MODE' = 1) /如果URL模式為1 那么就在GET中獲取控制器, 也就是說url地址是這種的http:/localh
37、ost/index.php?c=控制器&a=方法 $control = !empty($_GET'c') ? trim($_GET'c') : '' $action = !empty($_GET'a') ? trim($_GET'a') : '' else if($C'URL_MODE' = 2) /如果為2 那么就是使用PATH_INFO模式, 也就是url地址是這樣的 http:/localhost/index.php/控制器/方法/其他參數(shù) if(isset($_SER
38、VER'PATH_INFO') /$_SERVER'PATH_INFO'URL地址中文件名后的路徑信息, 不好理解, 來看看例子 /比如你現(xiàn)在的URL是那么你的$_SERVER'PATH_INFO'就是空的 /但是如果URL是/現(xiàn)在的$_SERVER'PATH_INFO'的值將會(huì)是 index.php文件名稱后的內(nèi)容 /abc/123/ $path = trim($_SERVER'PATH_INFO', '/'); /除去$_SERVER'PATH_INFO'兩邊的”/”$paths
39、 = explode('/', $path); $control = array_shift($paths); $action = array_shift($paths); /這里判斷控制器的值是否為空, 如果是空的使用默認(rèn)的 $_GET'c' = $control = !empty($control) ? $control : $C'DEFAULT_CONTROL' /和上面一樣 $_GET'a' = $action = !empty($action) ? $action : $C'DEFAULT_ACTION'
40、 ?> 注釋寫的很清楚, 這里我就不多說了, 做到這, 你就可以建立一個(gè)Controller目錄, 然后在目錄中建立文件 寫入如下內(nèi)容 <?php class Welcome public function index() echo 'Hello' ?> 執(zhí)行程序你將會(huì)看到Hello 然后在寫一個(gè)方法 <?php class Welcome public function index() echo 'Hello' public function show() echo '方法名稱Show' ?> 再次運(yùn)行程序, 將u
41、rl地址改為 http:/你的域名/index.php/welcome/show/ 你會(huì)看到 '方法名稱Show' 好了, 看到這里我們的控制器其實(shí)已經(jīng)弄得差不多了 現(xiàn)在我來看看視圖基類 <?php class View protected $vars = array(); protected function assign() protected function display() ?> 是不是很熟悉這兩個(gè)方法, 呵呵, 用來給模板設(shè)置變量和顯示模板的. 和smarty一樣, $vars屬性是用來保持模板變量的數(shù)組, 我來寫完它. 先看看assign方法 <
42、;?php public function assign($var, $value) if(is_array($var) $this->vars = array_merge($this->vars, $var); else $this->vars$var = $vaule; ?> 很簡單, 首先有兩個(gè)參數(shù) $var模板變量名稱, $value對(duì)應(yīng)的值,先判斷$var是否是數(shù)組, 如果是那么將他于屬性$vars合并。將$var當(dāng)作下標(biāo)$value當(dāng)作值, 添加到屬性$vars中。再來看display方法 <?php public function display($
43、file) include(ROOT_PATH . '/Core/Template.class.php'); $this->template = Template:GetInstance(); $this->template->templatePath = ROOT_PATH . '/Views/' $this->template->cache = TRUE; $this->template->cachePath = ROOT_PATH . '/Cache/' $this->template->
44、;cacheLifeTime = 1; $this->template->templateSuffix = '.html' $this->template->leftTag = '' $this->template->rightTag = '' $templateFile = ROOT_PATH . '/Views/' . $file . '.html' if(!file_exists($templateFile) exit('模板文件' . $file .
45、39;不存在'); $this->template->display($file, $this->vars); ?> 這個(gè)看上去有點(diǎn)多, 不著急我們慢慢解釋。首先有一個(gè)參數(shù) $file 模板文件名稱, 不包括路徑以及后綴;然后引入模板類, 設(shè)置模板的參數(shù);先設(shè)置模板文件目錄, 然后是否開啟緩存, 然后緩存目錄, 緩存有效時(shí)間, 模板文件后綴, 左右定界符 然后組合出模板文件路徑 比如你傳入的$file值是index 那么就是對(duì)應(yīng)的模板文件就是 模板目錄/index.html 然后判斷模板文件是否存在, 不存在則提示錯(cuò)誤 然后在調(diào)用模板類實(shí)例的display方法將
46、模板文件名稱, 和模板變量傳入 這里這個(gè)模板類我就不多說了, 如果有興趣的朋友可以下載附件查看, 類中有詳細(xì)注視 這里既然設(shè)置了兩個(gè)目錄, 那么我們就去創(chuàng)建它, 在程序根目錄下建立 Views 和 Cache 兩個(gè)目錄, 后面會(huì)用到現(xiàn)在我們打開昨天寫好的 Controller.class.php 控制器類 在里面加入一個(gè)屬性 和 幾個(gè)方法 <?php protected $view = NULL; public function _construct() /實(shí)例化上面寫到的視圖類 $this->view = new View(); public function assign($v
47、ar, $value = '') $this->view->assign($var, $value); public function display($file) $this->view->display($file); ?> 現(xiàn)在進(jìn)入到Views目錄中建立一個(gè)模板命名為index.html 內(nèi)容如下 <html> <head> <title>$title</title> </head> <body> $body </body> </html> 控制器
48、類中也有assign方法, 他是調(diào)用構(gòu)造函數(shù)中創(chuàng)建的view類實(shí)例的assign方法 也就是我們上面定義的那個(gè) dispaly方法也一樣 現(xiàn)在我們打開文件, 修改index方法, 注意這里將Welcome類繼承自Controller類 <?php class Welcome extends Controller public function index() $this->assign('title', 'Hello World'); $this->assign('body', '小愷教你寫一個(gè)屬于自己的MVC框架
49、9;); $this->display('index'); ?> 現(xiàn)在你需要做的就是打開瀏覽器, 在地址欄中輸入 http:/yourdomain/Index.php 然后你將會(huì)看到 "小愷教你寫一個(gè)屬于自己的MVC框架" 如果出現(xiàn)了這行字, 那么恭喜你View層也搞定了。 我們來說模型的實(shí)現(xiàn). 在Core目錄中建立 Model.class.php 文件, 然后建立一個(gè)Model類 <?php class Model /數(shù)據(jù)庫連接句柄 protected $dbLink = NULL; ?> 現(xiàn)在來給他添加方法 <?php /*
50、 * 構(gòu)造器, 連接數(shù)據(jù)庫 * * access public * return void */ public function _construct() global $C; $this->dbLink = mysql_connect($C'DB_HOST', $C'DB_USER', $C'DB_PWD') or exit(mysql_error(); mysql_select_db($C'DB_NAME', $this->dbLink) or exit(mysql_error(); mysql_query(&qu
51、ot;SET NAMES $C'DB_CHAR'"); /* * 執(zhí)行SQl命令 * * access public * param string $sql * return resource */ public function Query($sql) $res = mysql_query($sql) or exit(mysql_error(); return $res; /* * 執(zhí)行SQl命令,返回是否執(zhí)行成功 * * access public * param string $sql * return bool */ public function Execu
52、te($sql) if(mysql_query($sql) return TRUE; return FALSE; /* * 返回處理后的結(jié)果集 * * access public * param resource $res 結(jié)果集 * return mixed */ public function Fetch($res, $type = 'array') $func = $type = 'array' ? 'mysql_fetch_array' : 'mysql_fetch_object' $row = $func($res);
53、return $row; ?> 這幾個(gè)方法很簡單, 就是一般的mysql操作. 不過多解釋 現(xiàn)在打開Config.php把內(nèi)容改為 <?php $C = array( 'URL_MODE' => 2, /URL模式, 1普通模式, 2 PATH_INFO模式 'DEFAULT_CONTROL' => 'welcome', /默認(rèn)調(diào)用的控制器 'DEFAULT_ACTION' => 'index', /默認(rèn)執(zhí)行的方法 'DB_HOST' => 'localh
54、ost', /mysql主機(jī) 'DB_USER' => 'root', /mysql用戶 'DB_PWD' => '', /mysql密碼 'DB_CHAR' => 'utf8', /字符集 'DB_NAME' => 'test', /使用的數(shù)據(jù)庫 ); ?> 然后在打開Controller.class.php 控制器基類 在里面加一個(gè)方法, 用來加載模型 <?php protected function LoadModel
55、($modelName) $modelFile = ROOT_PATH . '/Models/' . $modelName . '.class.php' /構(gòu)造模型文件路徑 !file_exists($modelFile) && exit('模型' . $modelName . '不存在'); /如果模型文件不存在提示錯(cuò)誤 include($modelFile); /存在, 則引入 $class = ucwords($modelName); /獲得模型類名 !class_exists($class) &&a
56、mp; exit('模型' . $modelName . '未定義'); /判斷是否定義了模型類, 如果沒有提示錯(cuò)誤 $model = new $class(); /實(shí)例化模型類 return $model; /返回實(shí)例 ?> 注釋很詳細(xì)也不做解釋了. 現(xiàn)在在根目錄下家里Models目錄, 然后建立一個(gè)文件內(nèi)容很簡單, 繼承自Model類就行了 <?php class Test extends Model ?> 然后在自定義的控制器中修改index方法 <?php public function index() $model = $thi
57、s->LoadModel('test'); /載入模型 $res = $model->Query("SELECT * FROM reg"); /查詢表, 這里查詢你有的表就行了 $row = $model->fetch($res); /處理結(jié)果集返回?cái)?shù)組 print_r($row); /打印出來 ?> 這樣模型也搞定了, 這里只是是拋磚引玉, 不對(duì)的地方希望大家指出. 知道大概后你可以自己擴(kuò)展, 比如做出多語言, 數(shù)據(jù)庫抽象層, 等等等. MVC是什么MVC是什么?MVC是一種設(shè)計(jì)模式,將一個(gè)應(yīng)用程序分為三個(gè)部分Model(模型),V
58、iew(視圖), Controller(控制器),在程序中各自負(fù)責(zé)處理自己的任務(wù).SUN公司在JSP中將它發(fā)揮的淋漓盡致,尤其在structk中,它采用JSP來做View,severlet來做Controller,Bean做Model,最大程度上提高了程序的可維護(hù)性與協(xié)調(diào)開發(fā)性,在最近開發(fā)的一個(gè)項(xiàng)目中我就使用了這種思想,現(xiàn)在就拿出來給大家分享,讓更多人明白它的實(shí)現(xiàn)機(jī)理.首先來介紹一下MVC.所謂的M,英文為model,是模型的意思,這里可能譯為中文就不好理解了,不過沒關(guān)系,大家只要明白它是用來表示業(yè)務(wù)數(shù)據(jù)及業(yè)務(wù)規(guī)則的,再說的通俗一點(diǎn),就是由它來對(duì)業(yè)務(wù)數(shù)據(jù)庫進(jìn)行操作,并在操作之前對(duì)數(shù)據(jù)進(jìn)行驗(yàn)證.實(shí)際上它就是以類的方式實(shí)現(xiàn)以往的函數(shù)的形式,只是將它更有效的組織起來罷了,這就是邏輯業(yè)務(wù)層. 所謂的V,英文為view,視圖的意思,簡單講就是一個(gè)WEB界面,用戶通過提交請(qǐng)求來得到自己希望得到的頁面,這個(gè)頁面就是一個(gè)view,如果使用過VB或是DELPHI之類的RAD開發(fā)工具,大家就是想到,實(shí)際上V就是它們之中的那個(gè)form,就是那個(gè)使用鼠標(biāo)拖拉出來的界面.controller-viewmodeldatabase用戶瀏覽器呈現(xiàn)頁面BA所謂的C,英文為controller,英文意思為控制器,控制什么東西呢?控制的內(nèi)容其實(shí)有兩種:1.用戶的請(qǐng)求2.view的顯
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 項(xiàng)目食品采購合同協(xié)議
- 隱私作協(xié)議合同協(xié)議
- 陶瓷旋風(fēng)子合同協(xié)議
- 閑置乳化機(jī)采購合同協(xié)議
- 防火門買買合同協(xié)議
- 露臺(tái)房源出售合同協(xié)議
- 項(xiàng)目分包協(xié)議合同協(xié)議
- 陪同健身協(xié)議書范本
- 露天煤礦出租合同協(xié)議
- 非全日用工合同協(xié)議
- 廣州數(shù)控GSK 980TDc車床CNC使用手冊(cè)
- 紅色經(jīng)典影片與近現(xiàn)代中國發(fā)展學(xué)習(xí)通超星期末考試答案章節(jié)答案2024年
- 小學(xué)語文“跨學(xué)科學(xué)習(xí)任務(wù)群”內(nèi)涵及解讀
- 申請(qǐng)開票額度合同范本
- 2024年安全員C證考試題庫附答案
- 2024年生態(tài)環(huán)境執(zhí)法大練兵比武競賽理論考試題庫-下(多選、判斷題)
- 醫(yī)院創(chuàng)建服務(wù)基層行創(chuàng)建資料(3.5.2醫(yī)院感染相關(guān)監(jiān)測C)
- 2024年山東省東營市中考道德與法治試卷真題(含答案)
- 河南省安陽市林州市2023-2024學(xué)年八年級(jí)下學(xué)期6月期末歷史試題(解析版)
- 遼寧省沈陽市2023-2024學(xué)年高一下學(xué)期期中考試數(shù)學(xué)試卷(解析版)
- 四年級(jí)語文國測模擬試題 (1)附有答案
評(píng)論
0/150
提交評(píng)論