PHP學習筆記,本身動手寫個MVC的框架

最新在你們本身的博客的過程當中,發現各類開源的博客系統都或多或少的用起來彆扭.因而想動手本身寫個博客系統.既然寫,就想好好寫.那就先寫個MVC框架.一點一點來.寫的過程當中有不少想法.還但願你們可以多多指正.我在這裏先把它們記錄下來.下面是我對這個系統的一些想法.php

1,我要實現一個模塊話的博客系統,可以進行二次開發.mysql

2,我要實現apache和nginx的rewrite功能.nginx

3,我要實現對多數據庫的支持.包括mongodb和mysql 還有mysqli.等.sql

4,我要把smarty用起來.mongodb

好,下面動手開始寫.首先一點我得設計一下這個系統.大概的目錄結構是下面這個樣子的(我參考了PHPCMS).數據庫

/apache

./log--這個是日誌目錄.我想把日誌記錄在這個裏面數組

./system ---這個是系統目錄mvc

  ./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裏面用來返回默認的參數

裏面的內容大概是介個樣子滴:

<?php
	return array(
		  'default' =>
		   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文件.裏面寫以下的內容.

<?php
class c_index extends ctrl{
	public function __construct(){
		parent::__construct();
	}
	public function init(){
		echo "hello my mvc!";
	}
}

  再來訪問咱們的根域名,那麼咱們就會獲得hello my mvc.這句話的輸出.

 

 

----------------------------------------------------------------------------------------------------------------------------------

畢竟是本身我的的思路.若是有什麼不妥的地方,歡迎你們拍磚,也但願你們可以一塊兒來參與討論,最近看到php的相關板塊不像之前那麼火了.還但願你們可以多多來參與發帖和討論.

相關文章
相關標籤/搜索