PHP仿tp實(shí)現(xiàn)mvc框架基本設(shè)計(jì)思路與實(shí)現(xiàn)方法分析
本文實(shí)例講述了PHP仿tp實(shí)現(xiàn)mvc框架基本設(shè)計(jì)思路與實(shí)現(xiàn)方法。分享給大家供大家參考,具體如下:
仿tp mvc基本設(shè)計(jì)與簡(jiǎn)單實(shí)現(xiàn)
一:文件加載常識(shí)
變量 常量 函數(shù) 類
文件加載的函數(shù)或者使用命名空間:require();
require_once();
include();
include_once();
常量:define("DEFINE","");
const constant = "value";
函數(shù):function fun(){}
// global 使用全局變量 局部變量不被外部調(diào)用。
類:
<?php class A{ public $a = 10; public function aa(){ // 不能使用一個(gè)a是因?yàn)?,new A 之后 方法a會(huì)被自動(dòng)執(zhí)行,所以方法名不可以和類名沖突。 echo $this->a; // 輸出屬性. } public function __construct(){ // 構(gòu)造方法,實(shí)例化后自動(dòng)執(zhí)行, echo $this->bb(); // 調(diào)用方法。 } public function bb(){ echo "我是bb"; } } $a = new A; $a->aa(); class B extends A{ // 繼承 A ,類A是類B的父級(jí)。繼承public的, } $b = new B; $b->aa(); // 可以輸出類A里面的屬性。
工廠模式參閱:http://www.dbjr.com.cn/article/140658.htm
//-----------------------------工廠模式-------------------------// class A{ public $class; // public $class = $_GET['c']; //類名 public $method; // public $method = $_GET['m']; //方法 public function __construct($class,$method){ // 或者通過(guò) $_SERVER['PATH_INFO']; 轉(zhuǎn)換得到類名或者方法名(下面講解)。 $this->class = ucfirst(strtolower($class)).'Controller'; //對(duì)類名進(jìn)行安全處理,并加上控制器后綴 $this->method = strtolower($method); //對(duì)方法名進(jìn)行安全處理 $this->work($this->class,$this->method); } public function work($class,$method){ // 把文件命名成 (類名.class.php的形式),就可以通過(guò)類名找到文件。 //include '文件名(文件在別的地方)'; #例如 include './index.php'; 引入文件然后實(shí)例化類。 $c = new $class; //實(shí)例化類 $c->$method(); //訪問(wèn)類的方法 } }
至此我們可以通過(guò)url的 $_GET 參數(shù)來(lái)解決
例如:http://mvc.com/index.php?h=home&v=Index&c=index.html
h為前后臺(tái),v為控制器,c為模板。
$v = $_GET['v']; $c = rtrim($_GET['c'],".html"); new A($v,$c); // 根據(jù)繼承關(guān)系再次加載文件。 // extract($arr); //extract 的作用:從數(shù)組中將變量導(dǎo)入到當(dāng)前的符號(hào)表,鍵做變量,值做值! // compact(); // — 建立一個(gè)數(shù)組,包括變量名和它們的值 // assign display 實(shí)現(xiàn)參閱:http://www.dbjr.com.cn/article/140661.htm
class Controller{ public $array; public $key; public $val; public function assign($key,$val){ if(array($val)){ $this->array["$key"] = $val; }else{ $this->array["$key"] = compact($val); } } public function display($tpl = ''){ // 模板為空自動(dòng)加載。 $this->assign($this->key,$this->val); extract($this->array); // 如果模板為空就在這里根據(jù)get參數(shù)添加或者通過(guò) $_SERVER['PATH_INFO']; 轉(zhuǎn)換得到。(下面講解) if(file_exists($tpl)){ //模板存在就加載文件。 include $tpl; } } } //繼承總model。這個(gè)model名字和控制器model的名字是一樣的。繼承方法同Controller,總model必須需要加上一個(gè)return。數(shù)據(jù)處理的indexmodel可以加return,也可以不加。 class IndexModel extends Model{ public function index(){ // 數(shù)據(jù)處理。 // 需要返回?cái)?shù)據(jù)就加上return。 } } class IndexController extends Controller{ // 繼承 public function index(){ $m = Model("index"); echo '實(shí)例化后的index方法<br>'; $this->assign('m',$m); // 分配數(shù)據(jù)。 $this->display('index.html'); // 模板 } }
mvc雖然實(shí)現(xiàn)但是不夠人性化,因?yàn)槊看味家由蟝et參數(shù),變得很冗長(zhǎng),解決的關(guān)鍵在于$_SERVER['PATH_INFO'];
用這個(gè)替換掉h m v三個(gè)參數(shù)。
1. 當(dāng)輸入url為:http://mvc.com/index.php/home/index/index.html
這種情況下 index.php 斜線后面的apache會(huì)自動(dòng)認(rèn)為是一個(gè)路徑。
$_SERVER['PATH_INFO'] = /home/index/index.html
第1個(gè)斜線 /home 前后臺(tái)
第2個(gè)斜線 /index 控制器
第3個(gè)斜線 /index.html 模板文件
如果后面加有參數(shù)例如:?a=18&b=38 他不會(huì)被加到$_SERVER['PATH_INFO']里面。$_POST 或者 $_GET 也不會(huì)加入$_SERVER['PATH_INFO']里面的內(nèi)容,這樣就可以讓控制參數(shù)和數(shù)據(jù)的參數(shù)互不沖突。
2. U 方法的實(shí)現(xiàn)。重新改寫(xiě)$_SERVER['PATH_INFO']
參數(shù),改變?yōu)橐粋€(gè)數(shù)據(jù)。array( 'home', 'Index', 'index');
每次進(jìn)入入口文件index.php都把他的PHP_INFO參數(shù)轉(zhuǎn)換為數(shù)組,在控制器或者其他的地方只要調(diào)用這個(gè)參數(shù)就行了。
// 這里如果做了大小寫(xiě)的轉(zhuǎn)換,總控制器里面就不用了。 function bca(){ $arr = explode('/',ltrim($_SERVER['PATH_INFO'],'/')); if(count($arr) == 3){ $arr[0] = strtolower($arr[0]); $arr[1] = ucfirst(strtolower($arr[1])); // 判斷后綴是不是 .html if(substr($arr[2],-5,strlen($arr[2])) == '.html'){ $a = explode('.',$arr['2']); $arr[2] = strtolower($a[0]); }else{ $arr[2] = strtolower($arr[2]); } $_SERVER['PATH_INFO'] = $arr; } } // url方法做控制器或前后臺(tái)的跳轉(zhuǎn)。第三個(gè)參數(shù)是輸出還是return。默認(rèn)是直接輸出。 function U($string = '',$method = '',$bool = true){ // true 是直接輸出或者返回, // 獲取系統(tǒng)變量。 $path_info = $_SERVER['PATH_INFO']; $script_name = $_SERVER['SCRIPT_NAME']; // 判斷中間有沒(méi)有 / 以確定參數(shù)個(gè)數(shù)。 if(strpos($string,'/')){ $arr = explode('/',$string); if(count($arr) == 2){ // 兩個(gè)參數(shù)的情況。 $arr[0] = ucfirst(strtolower($arr[0])); $arr[1] = strtolower($arr[1]); $url = "/{$path_info[0]}/{$arr[0]}/{$arr[1]}.html"; }else if(count($arr) == 3){ // 三個(gè)參數(shù)的情況。 $arr[0] = strtolower($arr[0]); $arr[1] = ucfirst(strtolower($arr[1])); $arr[2] = strtolower($arr[2]); $url = "/{$arr[0]}/{$arr[1]}/{$arr[2]}.html"; } }else{ $arr = strtolower($string); // 一個(gè)參數(shù)的情況。 $url = "/{$path_info[0]}/{$path_info[1]}/{$arr}.html"; } // url 路徑的拼接。 if($method != ''){ $u = $script_name.$url.'?'.$method; if($bool == true){ echo $u; }else{ return $u; } }else{ $u = $script_name.$url; if($bool == true){ echo $u; }else{ return $u; } } }
3. url重寫(xiě),去掉 index.php
打開(kāi)apache配置文件重寫(xiě)模塊,LoadModule rewrite_module modules/mod_rewrite.so
根下加入的改寫(xiě)文件 .htaccess
內(nèi)容:
<IfModule mod_rewrite.c> Options +FollowSymlinks RewriteEngine On RewriteCond %{REQUEST_FILENAME} !-d RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^(.*)$ index.php/$1 [QSA,PT,L] </IfModule>
在瀏覽器輸入url:http://mvc.com/home/index/index.html?a=19b=38
[REDIRECT_STATUS] => 200 重寫(xiě)狀態(tài)ok。
發(fā)現(xiàn) $_SERVER['REDIRECT_URL'];
和 $_SERVER['PATH_INFO'];
參數(shù)相同。所以參數(shù)后面就可以去掉index.php這安全的問(wèn)題。
4. 模板替換(思路)
我們會(huì)發(fā)現(xiàn)有一個(gè)我們書(shū)寫(xiě)的模板,里面有 {$arr} <include file="" /> 等,我們把模板文件讀取后通過(guò)正則還有字符串把他轉(zhuǎn)換成正常的php文件。對(duì)文件名加密后放到替換后的文件夾下,每次url訪問(wèn)的時(shí)候查看是否有緩存文件,判斷最后修改時(shí)間等驗(yàn)證,
5. 數(shù)據(jù)緩存(思路)
json_encode()
json_decode()
file_get_contents()
file_put_contents();
unserialize();
serialize();
等存文文件里面或者memcache redis 等存儲(chǔ)。
更多關(guān)于PHP相關(guān)內(nèi)容感興趣的讀者可查看本站專題:《php面向?qū)ο蟪绦蛟O(shè)計(jì)入門(mén)教程》、《PHP數(shù)組(Array)操作技巧大全》、《PHP基本語(yǔ)法入門(mén)教程》、《PHP運(yùn)算與運(yùn)算符用法總結(jié)》、《php字符串(string)用法總結(jié)》、《php+mysql數(shù)據(jù)庫(kù)操作入門(mén)教程》及《php常見(jiàn)數(shù)據(jù)庫(kù)操作技巧匯總》
希望本文所述對(duì)大家PHP程序設(shè)計(jì)有所幫助。
- PHP從零開(kāi)始打造自己的MVC框架之類的自動(dòng)加載實(shí)現(xiàn)方法詳解
- PHP從零開(kāi)始打造自己的MVC框架之入口文件實(shí)現(xiàn)方法詳解
- php打造屬于自己的MVC框架
- PHP的MVC模式實(shí)現(xiàn)原理分析(一相簡(jiǎn)單的MVC框架范例)
- php實(shí)現(xiàn)最簡(jiǎn)單的MVC框架實(shí)例教程
- php實(shí)現(xiàn)簡(jiǎn)單的MVC框架實(shí)例
- 搭建自己的PHP MVC框架詳解
- PHP簡(jiǎn)單的MVC框架實(shí)現(xiàn)方法
- PHP MVC框架路由學(xué)習(xí)筆記
- PHP URL路由類實(shí)例
- php編寫(xiě)一個(gè)簡(jiǎn)單的路由類
- PHP從零開(kāi)始打造自己的MVC框架之路由類實(shí)現(xiàn)方法分析
相關(guān)文章
php快速u(mài)rl重寫(xiě)更新版[需php 5.30以上]
本代碼是在apache上的LoadModule rewrite_module modules/mod_rewrite.so運(yùn)行成功后的操作,利用php代碼對(duì)網(wǎng)站url重定向?yàn)楦鼜?fù)雜的邏輯結(jié)構(gòu)。2010-04-04php模仿asp Application對(duì)象在線人數(shù)統(tǒng)計(jì)實(shí)現(xiàn)方法
這篇文章主要介紹了php模仿asp Application對(duì)象在線人數(shù)統(tǒng)計(jì)實(shí)現(xiàn)方法,通過(guò)一個(gè)比較簡(jiǎn)單的自定義函數(shù)實(shí)現(xiàn)這一功能,具有一定參考借鑒價(jià)值,需要的朋友可以參考下2015-01-01PHP開(kāi)發(fā)之歸檔格式phar文件概念與用法詳解【創(chuàng)建,使用,解包還原提取】
這篇文章主要介紹了PHP開(kāi)發(fā)之歸檔格式phar文件概念與用法,結(jié)合實(shí)例形式較為詳細(xì)的分析了歸檔格式phar文件創(chuàng)建,使用,解包還原提取等概念及操作實(shí)現(xiàn)方法,需要的朋友可以參考下2017-11-11php curl post 時(shí)出現(xiàn)的問(wèn)題解決
這篇文章主要介紹了php curl post 時(shí)出現(xiàn)問(wèn)題的解決方法,需要的朋友可以參考下2014-01-01PHPStorm+XDebug進(jìn)行調(diào)試圖文教程
這篇文章主要為大家詳細(xì)介紹了PHPStorm+XDebug進(jìn)行調(diào)試圖文教程,內(nèi)容很豐富,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2016-06-06PHP Squid中可緩存的動(dòng)態(tài)網(wǎng)頁(yè)設(shè)計(jì)
有時(shí)我們需要控制主頁(yè)之類的網(wǎng)頁(yè)過(guò)期時(shí)間.但我們比如使用的是Chinacache的CDN,那要怎么樣設(shè)計(jì)才能讓他緩存我的內(nèi)容.2008-09-09PHP通過(guò)header實(shí)現(xiàn)文本文件下載的代碼
所謂實(shí)現(xiàn)文本文件的下載就是說(shuō)當(dāng)我們點(diǎn)擊一個(gè)文本文件的鏈接的時(shí)候不是打開(kāi)這個(gè)文件,而是彈出一個(gè)下載對(duì)話框讓我們下載2010-08-08