您好,登錄后才能下訂單哦!
這篇文章主要介紹了如何用PHP實(shí)現(xiàn)簡易的MVC框架的相關(guān)知識(shí),內(nèi)容詳細(xì)易懂,操作簡單快捷,具有一定借鑒價(jià)值,相信大家閱讀完這篇如何用PHP實(shí)現(xiàn)簡易的MVC框架文章都會(huì)有所收獲,下面我們一起來看看吧。
MVC的全名是Model View Controller
,是一種使用模型-視圖-控制器設(shè)計(jì)和創(chuàng)建web應(yīng)用程序的模式,是一種設(shè)計(jì)典范。
其中:
Model(模型):是應(yīng)用程序中用于處理應(yīng)用程序數(shù)據(jù)邏輯的部分,通常負(fù)責(zé)與數(shù)據(jù)庫直接進(jìn)行 curd 的交互。
View(視圖):是應(yīng)用程序處理數(shù)據(jù)顯示的部分,通過將處理好的數(shù)據(jù)進(jìn)行渲染。
Controller(控制器):是應(yīng)用程序中處理用戶交互的部分,通常用于處理數(shù)據(jù)邏輯的分發(fā),并相應(yīng)的反送給視圖和控制器。
優(yōu)點(diǎn):
低耦合
重用性高
部署快,生命周期成本低
可維護(hù)性高
缺點(diǎn):
增加了系統(tǒng)結(jié)構(gòu)和實(shí)現(xiàn)的復(fù)雜性
視圖與控制器間的過于緊密的連接
目前現(xiàn)在php主流的框架都已經(jīng)用到了mvc架構(gòu),例如:
thinkPHP
、Laravel
、Yii
都有mvc的架構(gòu)。
其中:
app目錄:用來存放視圖控制器模型等。
config目錄:用來存放框架的一些公共配置文件。
core目錄:用來存放一些基類文件,例如:控制器基類、模型基類、視圖基類、request請求基類、db鏈?zhǔn)讲僮骰惖取?/p>
static目錄:用來存放一些靜態(tài)資源,例如:圖片、html視圖文件、js、cs文件等。
index.php:整個(gè)框架的入口文件,進(jìn)行分發(fā)啟動(dòng)。
解析路由為什么是第一步呢?
只有成功解析路由以后,訪問到了某個(gè)類中的某個(gè)方法才可以使用MVC,因?yàn)榻馕雎酚梢彩强蚣軐?shí)現(xiàn)的最基礎(chǔ)的一部分,解析路由也少不了PHP的自動(dòng)加載機(jī)制
目前的php的自動(dòng)加載機(jī)制可以分為兩大機(jī)制,composer自動(dòng)加載機(jī)制和手動(dòng)實(shí)現(xiàn)自動(dòng)加載機(jī)制,該簡易框架通過手動(dòng)實(shí)現(xiàn)自動(dòng)機(jī)制來完成。
index.php
:
<?php//定義應(yīng)用目錄const APP_PATH = __DIR__ . '/'; //加載框架核心文件require(APP_PATH . 'core/Core.php'); //實(shí)例化框架類并運(yùn)行(new core\Core())->run();
代碼詳解:
第一步,定義了常量用來定義應(yīng)用目錄,后期可能會(huì)在某個(gè)地方就會(huì)用到。
第二步,加載框架核心文件 Core.php
,主要的核心邏輯也都集中在這個(gè)文件中。
第三步,實(shí)例化該類,并調(diào)用該類的run
方法。
Core.php
:
<?phpnamespace core;class Core{ public function run() { spl_autoload_register(array($this, 'loadClass')); $this->route(); } public function route() { $url = $_SERVER['REQUEST_URI']; $position = strpos($url, '?'); $url = $position === false ? $url : substr($url, 0, $position); $url = trim($url, '/'); if ($url) { //走URL指定控制器 $urlArray = explode('/', $url); $controllerName = ucfirst($urlArray[count($urlArray)-2]); $actionName = $urlArray[1]; }else{ //走默認(rèn)控制器 $controllerName = 'Index'; $actionName = 'index'; } $versionUrlArr = explode('/',$url); $versionUrlArr = array_slice($versionUrlArr,0,-2); $versionStr = implode('\\',$versionUrlArr); if (empty($versionStr)){ $versionStr = $versionStr; }else{ $versionStr = $versionStr.'\\'; } $controller = 'app\\controllers\\'.$versionStr. $controllerName . 'Controller'; if (!class_exists($controller)) { exit($controller . '控制器不存在'); } if (!method_exists($controller, $actionName)) { exit($actionName . '方法不存在'); } $dispatch = new $controller($controllerName, $actionName); $dispatch->$actionName(); } public function loadClass($className) { $className = str_replace('\\','/', $className); $file = $className . '.php'; if (file_exists($file)){ require_once $file; } }}
首先調(diào)用的是該類的 run
方法,run
方法主要負(fù)責(zé)調(diào)用運(yùn)行框架所需要 的一些方法,首先注冊了自動(dòng)加載方法 loadClass
,其后調(diào)用了的解析路由的方法(這兒是重點(diǎn),這兒實(shí)現(xiàn)了地址欄上輸入接口地址直接訪問控制器)。
注意:路由的解析規(guī)則是由我們自己來進(jìn)行定義的。
代碼詳解:
第一步:注冊自動(dòng)加載類,目的是為了路由解析、命名空間所使用。
第二步:調(diào)用路由解析方法,把地址欄上輸入的 域名/控制器名/方法名
給解析出來,并進(jìn)行調(diào)用。
經(jīng)過一系列解析后,最終 new 類名,調(diào)用方法名,來實(shí)現(xiàn)了路由的成功解析,從而訪問了某個(gè)類下面的某個(gè)方法。
$dispatch = new $controller($controllerName, $actionName);$dispatch->$actionName();
例如,要訪問app\controllers\StudentController.php
文件下的 demo 方法:
<?phpnamespace app\controllers;use core\base\Controller;class StudentController extends Controller{ public function demo() { echo '寫代碼的光頭強(qiáng)'; }}
通過第一步已經(jīng)完成了地址欄輸入路徑訪問到某個(gè)控制器中了,下面就需要在控制器中進(jìn)行 MVC 操作了。
控制器本身是已經(jīng)實(shí)現(xiàn)的,但是我們需要去繼承一個(gè)控制器基類在里面實(shí)現(xiàn)一些操作,例如:注冊一些全局異常類、注冊一些請求類、控制器之間的互相調(diào)用等。
視圖基類文件寫到了 core/base/View.php
文件里:
<?phpnamespace core\base;/** * 視圖基類 */class View{ protected $variables = array(); protected $_controller; protected $_action; function __construct($controller, $action) { $this->_controller = strtolower($controller); $this->_action = strtolower($action); } public function assign($name, $value) { $this->variables[$name] = $value; } public function render() { try { extract($this->variables); $file = APP_PATH . 'app/views/' . $this->_controller . '/' . $this->_action . '.php'; if (file_exists($file)){ require_once $file; }else{ require_once APP_PATH.'core/errorpage/404.html'; } }catch (\Exception $e){ echo $e->getMessage(); } }}
代碼詳解:
其中,視圖功能有兩大功能。
第一大功能:傳值(assign)。
我們一般傳值都是通過
$this->assign('name','寫代碼的光頭強(qiáng)');$this->assign('sex','男');
這種方法進(jìn)行傳值。
在框架中實(shí)現(xiàn)的方法為:
public function assign($name, $value){ $this->variables[$name] = $value;}
很明顯的可以看出,將所有的鍵值對放到了一個(gè)數(shù)組中。
第二大功能:視圖映射(render)
實(shí)現(xiàn)代碼:
public function render(){ extract($this->variables); $file = APP_PATH . 'app/views/' . $this->_controller . '/' . $this->_action . '.php'; if (file_exists($file)){ require_once $file; }else{ require_once APP_PATH.'core/errorpage/404.html'; }}
接收到控制器名方法名,拼接到自定義視圖解析規(guī)則地址上,直接引入即可。
實(shí)現(xiàn)模型的靈魂就是要控制器名作為表名來使用。
控制器中:
$data = ['name' => 'tom'];$model = new StudentModel();$model->addData($data);
自定義的模型中:
<?phpnamespace app\models;use core\base\Model;class StudentModel extends Model{ protected $table = 'student'; public function addData($data) { $this->add($data); }}
模型基類:
<?phpnamespace core\base;use core\db\Orm;class Model extends Orm{ protected $table; public function __construct() { echo $this->table; } public function add($data){ //處理添加邏輯 }}
在模型基類中我們可以自定義orm來完成與數(shù)據(jù)庫的交互操作
關(guān)于“如何用PHP實(shí)現(xiàn)簡易的MVC框架”這篇文章的內(nèi)容就介紹到這里,感謝各位的閱讀!相信大家對“如何用PHP實(shí)現(xiàn)簡易的MVC框架”知識(shí)都有一定的了解,大家如果還想學(xué)習(xí)更多知識(shí),歡迎關(guān)注億速云行業(yè)資訊頻道。
免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。