本文實例講述了PHP仿tp實現mvc框架基本設計思路與實現方法。分享給大家供大家參考,具體如下:
仿tp mvc基本設計與簡單實現
一:文件加載常識
變量 常量 函數 類
文件加載的函數或者使用命名空間:require();
require_once();
include();
include_once();
常量:define("DEFINE","");
const constant = "value";
函數:function fun(){}
// global 使用全局變量 局部變量不被外部調用。
類:
?php
class A{
public $a = 10;
public function aa(){ // 不能使用一個a是因為,new A 之后 方法a會被自動執行,所以方法名不可以和類名沖突。
echo $this->a; // 輸出屬性.
}
public function __construct(){ // 構造方法,實例化后自動執行,
echo $this->bb(); // 調用方法。
}
public function bb(){
echo "我是bb";
}
}
$a = new A;
$a->aa();
class B extends A{ // 繼承 A ,類A是類B的父級。繼承public的,
}
$b = new B;
$b->aa(); // 可以輸出類A里面的屬性。
工廠模式參閱:https://www.jb51.net/article/140658.htm
//-----------------------------工廠模式-------------------------//
class A{
public $class; // public $class = $_GET['c']; //類名
public $method; // public $method = $_GET['m']; //方法
public function __construct($class,$method){
// 或者通過 $_SERVER['PATH_INFO']; 轉換得到類名或者方法名(下面講解)。
$this->class = ucfirst(strtolower($class)).'Controller'; //對類名進行安全處理,并加上控制器后綴
$this->method = strtolower($method); //對方法名進行安全處理
$this->work($this->class,$this->method);
}
public function work($class,$method){
// 把文件命名成 (類名.class.php的形式),就可以通過類名找到文件。
//include '文件名(文件在別的地方)'; #例如 include './index.php'; 引入文件然后實例化類。
$c = new $class; //實例化類
$c->$method(); //訪問類的方法
}
}
至此我們可以通過url的 $_GET 參數來解決
例如:http://mvc.com/index.php?h=homev=Indexc=index.html
h為前后臺,v為控制器,c為模板。
$v = $_GET['v'];
$c = rtrim($_GET['c'],".html");
new A($v,$c); // 根據繼承關系再次加載文件。
// extract($arr); //extract 的作用:從數組中將變量導入到當前的符號表,鍵做變量,值做值!
// compact(); // — 建立一個數組,包括變量名和它們的值
// assign display 實現參閱:https://www.jb51.net/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 = ''){ // 模板為空自動加載。
$this->assign($this->key,$this->val);
extract($this->array);
// 如果模板為空就在這里根據get參數添加或者通過 $_SERVER['PATH_INFO']; 轉換得到。(下面講解)
if(file_exists($tpl)){ //模板存在就加載文件。
include $tpl;
}
}
}
//繼承總model。這個model名字和控制器model的名字是一樣的。繼承方法同Controller,總model必須需要加上一個return。數據處理的indexmodel可以加return,也可以不加。
class IndexModel extends Model{
public function index(){
// 數據處理。
// 需要返回數據就加上return。
}
}
class IndexController extends Controller{ // 繼承
public function index(){
$m = Model("index");
echo '實例化后的index方法br>';
$this->assign('m',$m); // 分配數據。
$this->display('index.html'); // 模板
}
}
mvc雖然實現但是不夠人性化,因為每次都要加上get參數,變得很冗長,解決的關鍵在于$_SERVER['PATH_INFO'];
用這個替換掉h m v三個參數。
1. 當輸入url為:http://mvc.com/index.php/home/index/index.html
這種情況下 index.php 斜線后面的apache會自動認為是一個路徑。
$_SERVER['PATH_INFO'] = /home/index/index.html
第1個斜線 /home 前后臺
第2個斜線 /index 控制器
第3個斜線 /index.html 模板文件
如果后面加有參數例如:?a=18b=38 他不會被加到$_SERVER['PATH_INFO']里面。$_POST 或者 $_GET 也不會加入$_SERVER['PATH_INFO']里面的內容,這樣就可以讓控制參數和數據的參數互不沖突。
2. U 方法的實現。重新改寫$_SERVER['PATH_INFO']
參數,改變為一個數據。array( 'home', 'Index', 'index');
每次進入入口文件index.php都把他的PHP_INFO參數轉換為數組,在控制器或者其他的地方只要調用這個參數就行了。
// 這里如果做了大小寫的轉換,總控制器里面就不用了。
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方法做控制器或前后臺的跳轉。第三個參數是輸出還是return。默認是直接輸出。
function U($string = '',$method = '',$bool = true){ // true 是直接輸出或者返回,
// 獲取系統變量。
$path_info = $_SERVER['PATH_INFO'];
$script_name = $_SERVER['SCRIPT_NAME'];
// 判斷中間有沒有 / 以確定參數個數。
if(strpos($string,'/')){
$arr = explode('/',$string);
if(count($arr) == 2){ // 兩個參數的情況。
$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){ // 三個參數的情況。
$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); // 一個參數的情況。
$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重寫,去掉 index.php
打開apache配置文件重寫模塊,LoadModule rewrite_module modules/mod_rewrite.so
根下加入的改寫文件 .htaccess
內容:
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 重寫狀態ok。
發現 $_SERVER['REDIRECT_URL'];
和 $_SERVER['PATH_INFO'];
參數相同。所以參數后面就可以去掉index.php這安全的問題。
4. 模板替換(思路)
我們會發現有一個我們書寫的模板,里面有 {$arr} include file="" /> 等,我們把模板文件讀取后通過正則還有字符串把他轉換成正常的php文件。對文件名加密后放到替換后的文件夾下,每次url訪問的時候查看是否有緩存文件,判斷最后修改時間等驗證,
5. 數據緩存(思路)
json_encode()
json_decode()
file_get_contents()
file_put_contents();
unserialize();
serialize();
等存文文件里面或者memcache redis 等存儲。
更多關于PHP相關內容感興趣的讀者可查看本站專題:《php面向對象程序設計入門教程》、《PHP數組(Array)操作技巧大全》、《PHP基本語法入門教程》、《PHP運算與運算符用法總結》、《php字符串(string)用法總結》、《php+mysql數據庫操作入門教程》及《php常見數據庫操作技巧匯總》
希望本文所述對大家PHP程序設計有所幫助。
您可能感興趣的文章:- PHP從零開始打造自己的MVC框架之類的自動加載實現方法詳解
- PHP從零開始打造自己的MVC框架之入口文件實現方法詳解
- php打造屬于自己的MVC框架
- PHP的MVC模式實現原理分析(一相簡單的MVC框架范例)
- php實現最簡單的MVC框架實例教程
- php實現簡單的MVC框架實例
- 搭建自己的PHP MVC框架詳解
- PHP簡單的MVC框架實現方法
- PHP MVC框架路由學習筆記
- PHP URL路由類實例
- php編寫一個簡單的路由類
- PHP從零開始打造自己的MVC框架之路由類實現方法分析