MVC淺談
要學習MVC我們要先了解MVC:MVC模式(Model-View-Controller)由Trygve Reenskaug在1974年提出,是施樂帕羅奧多研究中心(Xerox PARC)在20世紀80年代爲程序語言Smalltalk發明的一種軟件設計模式。MVC模式的目的是實現一種動態的程式設計,使後續對程序的修改和擴展簡化,並且使程序某一部分的重複利用成爲可能。簡單來說,MVC模式通過對複雜度的簡化,使程序結構更加直觀。運用MVC我們就可以更加直觀的管理我們的代碼;
爲什麼要自己構建MVC?你自己的心裏可能已經有了一個答案,總體來說分爲三個方向:①爲了更快的開發效率,畢竟自己的東西纔是最得心應手的;②爲了更高的運行效率,市場上很多框架功能強大,擴展充足,但我很多方面我們都不需要;所以我們要開發出最適合自己的;爲自己量身定做的一個框架;③爲了拓展自己的知識,構建MVC可以使我們更好的熟悉代碼,增加的自己技能;
初步瞭解MVC流程
通過入口文件->進入文件後定義一些常量->引入需要的函數->自動加載需要的類->就可以啓動框架了;
啓動以後我們就要運用網址傳輸所需要的指令數據;->用路由解析->根據解析加載相應控制器->最後返回結果;
入口文件
入口文件是MVC框架所必需的用於更加方便的管理流入數據;怎樣構建入口文件?1:定義常量.2:加載數據庫;3:啓動框架
①定義常量
使用define函數定義;
基本需要的常量有:
1:define('IMOOC',realpath(' ./'));定義文件根目錄,已此爲目標查找其他文件;
2:define('CORE',IMOOC.'/core');定義框架核心文件目錄;
3:define('APP',IMOOC.'/app');定義項目文件目錄(比如控制器,模型等)
此外還需要一個變量
define('DEBUG",true);調試模式;默認開啓根據判斷這個值是否開啓調試
if(DEBUG){開啓}else{關閉};
在這裏我們應用了一個封裝功能P;可以更美觀的打印值
<?php
function p($var)
{
if(is_bool($var)) {
var_dump($var);
}else if(is_null($var)) {
var_dump($var);
}else{
echo "<pre style='position: relative;z-index: 1000;padding: 10px;border-radius: 5px;background:#F5F5F5;border: 1px solid #aaa;font-size: 14px;line-height: 18px;opacity: 0.9;'>".print_r($var,true)."</pre>";
}
}
?>
②加載類方法
//加載函數庫includeCORE.'/common/function.php';引用此文件CORE就是定義的核心文件目錄
使用P()打印輸出;
爲了更方便的管理我們啓動框架需要的類值,我們需要建立一個自動加載類庫同樣放在覈心目錄/加載函數庫includeCORE.'/imooc.php';引用此文件;
<?php
namespace core; //命名空間
class imooc
{
static public function run() //進入入口文件需要調用的類,因爲應用類較多所以用靜態方法;
{
p('OK');
}
}
③啓動框架在入口文件調用執行;通過\core\immooc::run();調用;輸出OK成功啓動框架
加載需要的類
①spl_autoload_register('\core\imooc::load');//實例化類不存在則觸發此函數;
②
//自動加載類庫
<pre name="code" class="php">public static $classMap=array();//定義一個數組,用於儲存緩存
static public function run()//加載路由類
{
p('ok');
$route= new \core\route();//實驗加載路由類
}
static public function load($class)//$class就是我們需要自動引入的類 { //自動加載類庫 //new \core\route();//引入類 //$class = '\core\route';//如果沒有引入此類則觸發函數 //IMOOC.'/core/route.php';//然後需要轉換爲此種類型 //p($class); //p(IMOOC.$class.'.php'); if(isset($classMap[$class])){//爲了必反重複調用,可以首次調用後存入數組緩存 return true; }else{ $calss=str_replace('\\','/',$class);//使用str_replace將斜槓替換'\'需要用那個'\'轉義 $file=IMOOC.'/'.$calss.'.php'; if(is_file($file)){//判斷文件是否存在,存在則引用 include $file; self::$classMap[$class]=$class; }else{ return false; } } }
<?php
namespace core\lib;
use core\lib\conf;
//路由類
class route
{
public function __construct()
{
p('OK');//隨意輸出實驗是否加載;
}
}
③輸出OK成功;
路由類
簡歷lib文件存放路由類:
在這裏需要用到僞靜態;".htaccess";
<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php? [QSA,PT,L]
</IfModule>
設置好以後
<?php
namespace core\lib;
use core\lib\conf;
//路由類
class route
{
public function __construct()
{<span style="font-size:12px;"> </span><span style="color:#808080;background-color:#f7faff;font-style:italic;"><span style="font-size:12px;">
//xxx.com/index.php/index/index/實際訪問網址
</span></span><pre name="code" class="php"><span style="color:#808080;background-color:#f7faff;font-style:italic;"><span style="font-size:12px;">
//xxx.com/index/index/地址欄訪問網址</span></span>
/* *1.隱藏index.php *2.獲取到URL參數部分 *3.返回對應的控制器和方法 */可以用
$_SERVER['REQUEST_URI']判斷值傳遞
if(isset($_SERVER['REQUEST_URI']) && $_SERVER['REQUEST_URI'] != '/'){
//index/index
<pre name="code" class="php"><span style="color:#808080;background-color:#f7faff;font-style:italic;"><span style="font-size:12px;"></span></span><pre name="code" class="php">//因爲值傳遞爲/id/2/name/2;所以可以先分割爲數組再取值
$path=$_SERVER['REQUEST_URI']; //p($path).'<br>'; $patharr=explode('/',trim($path,'/'));//分割 //p($patharr); if(isset($patharr[0])){ $this->ctrl=$patharr[0]; } unset($patharr[0]); if(isset($patharr[1])){ $this->action=$patharr[1]; unset($patharr[1]); }else{
$this->action = conf::get('ACTION','route'); } //url多餘部分轉換爲GET; //p($patharr); //p($_GET);<span style="color:#808080;background-color:#f7faff;font-style:italic;"><span style="font-size:12px;"></span></span><pre name="code" class="php"><pre name="code" class="php"><pre name="code" class="php">//因爲值傳遞爲/id/2/name/3;所以需要分割以後獲取值;
//獲取後爲array(
'id'=>2
'name'=>3
)
$count=count($patharr)+2;//因爲從第三個開始,初始值爲0;所以需要加2 $i=2; while($i<$count){ if(isset($patharr[$i+1])) { $_GET[$patharr[$i]] = $patharr[$i + 1]; } $i = $i + 2; } //p($_GET);//最後就可以截取到值了; }else{ $this->ctrl= conf::get('CTRL','route');; $this->action= conf::get('ACTION','route');;
};
}}
這樣我們可以通過解析到的值訪問控制器-方法-並傳遞參數了;