作者:沙袋
作為PHP Coder的入門進階,自己動手寫一個MVC框架可以從各方面鞏固和加深你對PHP的理解,還能瞭解一些架構方面的基礎知識。
1. 什麼是MVC
MVC(Model-View-Controller,模型-檢視-控制器)是PHP最常見的一種開發模式。它將程式劃分為三層。
- 最上面的一層,是直接面向終端使用者的"檢視層"(View)。它負責給使用者提供操作介面,是程式的外殼。
- 最底下的一層,是核心的"模型層"(Model),負責檢索、組織和處理程式所需的資料或資訊。
- 中間的一層,就是"控制層"(Controller),它負責根據使用者從"檢視層"輸入的指令,選取"模型層"中的資料,然後根據業務邏輯對其進行相應的操作,併產生最終結果。
2. 起步
檔案結構如下
www目錄將作為網站的根目錄,可以在Apache或Nginx的vhost配置中將www指定為Document Root,將核心程式碼放在根目錄以外,使得使用者無法直接訪問到核心程式碼,提高整站的安全性。
3. 入口
既然www是根目錄,那www下的index.php就可以作為整站的入口,當然,你也可以在www下繼續寫usercenter.php、admin.php等來作為其它模組的入口,你只需要制定規則就好。
而作為入口,由於它可以接收到發往它的所有資料,因此可以按照框架制定的路由規則對資料進行分發處理。因此,在入口,需要引入初始化程式,然後進行路由分發。
/* Nova/www/index.php */
<?php
//給目錄定義一些常量
define('ROOT_DIR', __DIR__.'/..');
define('APP_DIR', ROOT_DIR.'/Application');
define('CONFIG_DIR', ROOT_DIR.'/config');
define('FRAMEWORK_DIR', ROOT_DIR.'/Framework');
define('LOG_DIR', ROOT_DIR.'/logs');
define('WWW_DIR', __DIR__.'/');
//設定一下站點的時區
define('TIMEZONE', 'Asia/Shanghai');
ini_set('data.timezone', TIMEZONE);
//引入初始化程式
require FRAMEWORK_DIR.'/init.php';
4. 初始化程式
/* Nova/Framework/init.php */
<?php
namespace Nova\Framework;
//引入配置檔案
require CONFIG_DIR . '/config.php';
引入自動載入類
require 'Autoloader.php';
//初始化自動載入
Autoloader::init();
//啟用Session
Session::start();
//啟動核心處理程式
$core = new Core;
$core->run();
初始化的過程涉及到了自動載入類及Session的處理,這兩部分我們稍後介紹。先來說說核心處理程式,我把路由分發邏輯放在了這裡。
5. 核心處理程式
/* Nova/Framework/Core.php */
<?php
namespace Nova\Framework;
class Core
{
public function run()
{
$this->setReporting();
$this->route();
}
/**
* 設定整站的錯誤報告等級
*/
public function setReporting()
{
if (DEBUG_MODE === true) {
error_reporting(E_ALL);
ini_set('display_errors', 'On');
} else {
error_reporting(E_ALL);
ini_set('display_errors', 'Off');
ini_set('log_errors', 'On');
ini_set('error_log', LOG_DIR . 'error.log');
}
}
/**
* 路由規則
*
* 使用$_REQUEST['act']來定位控制器的類
* 使用$_REQUEST['st']來定位具體的方法
*/
public function route()
{
//如果$_REQUEST中沒有'act',則設定預設act為index
if (!isset($_REQUEST['act'])) {
$_REQUEST['act'] = 'index';
}
//如果$_REQUEST中沒有'st',則設定預設act為main
if (!isset($_REQUEST['st'])) {
$_REQUEST['st'] = 'main';
}
//根據act定位控制器類
$className = 'Nova\\Application\\Controllers\\' . $_REQUEST['act'];
//判斷控制器類是否存在,不存在則報404
if (!class_exists($className)) {
header('HTTP/1.1 404 Not Found');
die($className);
}
//生成目標控制器類物件
$obj = new $className();
//判斷方法是否存在,不存在則報404
if (!method_exists($obj, $_REQUEST['st'])) {
header('HTTP/1.1 404 Not Found');
exit;
}
//執行目標方法
$obj->$_REQUEST['st']();
}
}
你可以在Github上檢視Nova專案的原始碼。
如果你有任何問題或建議,可以掃描下方二維碼或者微信搜尋[phpjiagoushier],關注我的微信公眾號[PHP架構],與我交流互動。
本作品採用《CC 協議》,轉載必須註明作者和本文連結