最新在大家自己的部落格的過程中,發現各種開源的部落格系統都或多或少的用起來彆扭.於是想動手自己寫個部落格系統.既然寫,就想好好寫.那就先寫個MVC架構.一點一點來.寫的過程中有很多想法.還希望大家能夠多多指正.我在這裡先把它們記錄下來.下面是我對這個系統的一些想法.
1,我要實現一個模組話的部落格系統,能夠進行二次開發.
2,我要實現apache和nginx的rewrite功能.
3,我要實現對多資料庫的支援.包括mongodb和mysql 還有mysqli.等.
4,我要把smarty用起來.
好,下面動手開始寫.首先一點我得設計一下這個系統.大概的目錄結構是下面這個樣子的(我參考了PHPCMS).
/
./log--這個是日誌目錄.我想把日誌記錄在這個裡面
./system ---這個是系統目錄
./lib--這個是系統庫.關鍵的東西都放在這裡面
./classes -- 這個是系統的相關類
./configs--這個是系統的設定檔目錄
./model--這個是各個資料模型的目錄
./modules--這個是各個模組的目錄
./base.php--所有的請求都路由到這個檔案上面來了,再有這個檔案來分發.
./index --我把index也當成一個模組來寫
./templates--這個是模板目錄
./default--這個是預設的模板目錄
./cache--這個是cache目錄.
index.php-----------這個是單入口檔案,用來路由相關的請求.
MVC架構要把model和ctrl還有view分開.那麼就需要url的路由.至於偽靜態什麼的,後面再說.要先滿足最基本的需求.
MVC架構要有個單入口檔案,於是第一個檔案產生了.就是根目錄下面的index.php,這個檔案用來接收所有的請求,也就是說所有的請求都是從這個入口進來的.關於單入口的好處,請自行搜尋腦補.
每一個資料模型,按照我的理解,應該對應一張或者多張表.比如文章模型.可以單獨對文章表.也可以對應作者表and文章表and評論表.
涉及到資料模型就要與資料庫打交道了.先不管跟資料庫打交道.我最先要實現的是能夠路由我的URL
最簡單的url http://網域名稱.com要路由到index模組下的index.php檔案裡面的index控制器並且執行這個控制器的預設方法(我設定成了init);
既然要有預設的路由參數,我就建立了一個檔案.叫default_arg.config.php 存放在/system/lib/configs/default_arg.config.php裡面用來返回預設的參數
裡面的內容大概是介個樣子滴:
array('m'=>'index','c'=>'index','a'=>'init',), );
當我想引用這些配置的時候 .我只需要如下的調用
$configs = include_once($file);
就能夠將這個大數組賦值到configs上面,如果沒有參數,就使用預設的參數.把預設參數拼接到URL上面.我的預設首頁就變成了
http://網域名稱.com/index.php?m=index&c=index&a=init
這一切的功能是怎麼實現的哦?
既然訪問的是index.php,那就從index.php開始看,其實index裡面就幾行,
define('ROOT_PATH',dirname(__FILE__));//定義一個系統路徑require_once(ROOT_PATH.DIRECTORY_SEPARATOR.'system'.DIRECTORY_SEPARATOR.'base.php');//引用架構的基礎類$sys = base::getInstance();//得到基礎類的執行個體,基礎類是一個單例類$sys->init();//調用單例類的init方法
其實DIRECTORY_SEPARATOR就是個/,我們可以這樣理解.引用了架構裡面的base檔案.然後調用了裡面的getInstance方法.得到了一個實力,最後調用了init方法.
為什麼要使用單例類,可以自行百度.這裡用單例類比較科學.後面我會把整個類貼上來,下面用到什麼就貼什麼.
再看看base類裡面的getInstance幹了些什麼.
class base{public static $sys;private function __construct(){return false;}public static function getInstance(){if(!(self::$sys instanceof self)){self::$sys = new self();}return self::$sys;}
因為是單例類,我把base裡面的構造方法聲明成了私人的.這是為了防止被new關鍵字從外部new這個類.為了保證所有操作都是由單一執行個體來完成的.這個類是不允許在外部new的.
在看看getInstance方法.先判斷自己的$sys變數是不是自己的執行個體.如果不是就將自己的執行個體賦值給$sys,如果是則不做操作,最後 返回了這個類自己的一個執行個體.
在看看init方法做了些什麼
public static function init(){self::sys_class('model');self::sys_class('ctrl');$args = self::__explan_arg();$ctrl = self::__load_ctrl($args['m'],$args['c']);call_user_func(array($ctrl,$args['a']));}
我在這個基礎類裡面寫了幾個方法.如果方法名稱前面有兩個底線,就是私人的方法. 有個sys_class就是在指定目錄載入系統了.這個目錄是/system/lib/class/. 這裡載入了model類和ctrl類,就是模型類的基類和控制器類的基類.這個ctrl類是所有控制器的基類.裡面可以寫一些公用的方法.比如說在構造方法讓類中有一個base的執行個體神馬的.讓所有的控制器都整合自這個類.這個model類目前還沒用到.但是以後的資料模型都應該是來自這個model類的.後面會說.
然後我調用了__explan_arg方法.這個方法就是來解析get得到的參數的.
private static function __explan_arg(){$default_arg = self::sys_config('default_arg');$args['m'] = isset($_GET['m'])?$_GET['m']:$default_arg['m'];$args['c'] = isset($_GET['c'])?$_GET['c']:$default_arg['c'];$args['a'] = isset($_GET['a'])?$_GET['a']:$default_arg['a'];return $args;}
我在第一行使用了一個sys_config方法來載入預設參數.這個方法就是在系統的/system/lib/configs/目錄下面找到對應的設定檔,上面已經說過了怎麼把數組返回.這樣當GET裡面沒有相應的參數的時候就會使用預設的參數.接下來我們調用了__load_ctrl方法載入了相應的控制器.傳入了m和c.這個方法實現的就是到m所指定的目錄下面找到c這個檔案並且執行個體化一個c這個類(也就是相應的控制器類.)並且返回相應控制器類的執行個體.然後我調用了一個call_user_func方法.因為我們沒辦法在程式裡像下面的樣子來調用控制器的方法
$ctrl->$args['a'];//這樣是沒辦法調用的
所以我們使用了call_user_func方法來調用相應控制器的方法.
好了,現在再縷縷我們程式的流程.首先訪問了index.php-->index.php定義了一個路徑,去引用了base類.並且得到了一個base類的執行個體.還調用了base的init方法.-->base的init方法做了下面的事情-->先去引用了基類model和ctrl-->去解析了url中的參數,得到了m,c,a-->通過m,c來引用相應的控制器,-->調用相應控制器的a方法.然後就會得到相應的輸出了.
到此為止我們的架構控制器部分基本算是完成了,預設的args是index,index,init.我們在/modules/index/裡面建立一個index.php檔案.裡面寫如下的內容.
再來訪問我們的根網域名稱,那麼我們就會得到hello my mvc.這句話的輸出.
----------------------------------------------------------------------------------------------------------------------------------
畢竟是自己個人的思路.如果有什麼不妥的地方,歡迎大家拍磚,也希望大家能夠一起來參與討論,最近看到php的相關板塊不像以前那麼火了.還希望大家能夠多多來參與發帖和討論.