1. 程式人生 > >做一個自己的MVC框架[php]

做一個自己的MVC框架[php]

外包的活幹多了,總有一些小專案,這些小專案甚至不需要考慮安全。這時候用框架顯得浪費。自己手寫原生程式碼又有些不太習慣(框架用多了,有時候連基本的都忘了,不能忘本啊。。。)
許久不更的部落格。反正也沒多少人看,哈~就當給自己一個馬克,也希望能給一些剛踏入程式猿大軍的新手們做到一個瞭解MVC拋磚引玉的小作用吧。
嘮嘮叨叨一些廢話,開始說真的。

———-我是分割線—————–
1.我對MVC的理解
再嘮叨一遍MVC三個字母的含義吧
M:model->模型。一般是操作資料的地方
V:view->檢視。使用者肉眼直接看到的介面
C:controller->控制器。控制整個應用的作用(好難全面解釋,比如之所以點儲存能夠儲存資訊而不是刪掉資訊,這就是控制器的作用)
所以,MVC結構在專案開發中的絕大部分作用就是從控制器(C)作為切入點[和個人習慣有關係,但是前提要架構好整體專案],呼叫模型介面(M)進行資料操作,並且展示在檢視(V)上,以視覺的方式直觀的反映給使用者。

2.預設框架的基本結構
因為比較熟悉CI框架,也用過TP框架所以基本結構如下:

1).一個框架要有一個入口檔案
2).框架和URL基本呼叫方式為
    http://基本網址/入口檔案/控制器的資料夾/控制器/方法?引數名=引數值&引數名=引數值

3.資料夾結構
這裡列出基本的檔案及資料夾的結構

-info..........................框架資料夾
    -config....................配置資料夾
        database.php...........資料庫配置檔案
    -controller................使用者控制器資料夾
        -test..................使用者控制器資料夾
            welcome.php........使用者控制器檔案
    -core......................本框架的一些核心檔案
        Info_Controller.php....框架的核心控制器
        Info_Model.php.........框架核心模型
        route.php..............框架的路由規則
    -models....................使用者模型資料夾
        user_model.php.........使用者模型檔案
    -views.....................使用者檢視資料夾
        welcome.html...........使用者檢視檔案
    index.php..................單入口檔案

4.開始~

0).但入口檔案設定基本資訊

<?php
    #info/index.php:
    #宣告專案根本目錄
    define("SERVER_ROOT",dirname(__FILE__));
    #宣告專案網址
    define("SITE_ROOT","localhost/info");
    #宣告檢視資料夾
    define("VIEWS_ROOT",dirname(__FILE__).'views');
    #宣告控制器資料夾
    define("CONTROLLER_ROOT",'/controllers');
    #引入框架核心控制器
require_once(SERVER_ROOT . "/core/Info_Controller.php"); #引入框架核心模型 require_once(SERVER_ROOT . "/core/Info_Model.php"); #引入路由 require_once(SERVER_ROOT . "/core/route.php");

1).路由 從URL獲取所有的目標資訊
URL:
localhost/info/index.php/test/welcome/hello.php?getKey=getValue
從上述URL可以提取到,
我們要呼叫welcome控制器下的hello方法,並且以GET方式傳入了引數名:getKey,引數值:getValue這樣一對k/v;
熟悉 $_SERVER 的應該知道這樣一個變數 :$_SERVER[‘PATH_INFO’]。
(可以通過 var_dump($_SERVER)檢視,如果沒有,則說明伺服器沒有開啟path_info,本文預設開啟)
該變數可以簡單地理解為記錄了從指令碼檔案(即單入口檔案)到傳參開始的完整路徑
即’/test/welcome/hello.php’部分,所以我們要利用該變數分割出資料夾、控制器以及方法。直接上程式碼比較明顯

<?php 
    #info/core/index.php
    #獲取controller和function
    $pathInfo = $_SERVER['PATH_INFO'];
    $pathArr = explode('/', $pathInfo);#分割資料夾、控制器和方法
    array_shift($pathArr);#刪除第一個空元素,因為PATH_INFO以'/'開始
    $length = sizeof($pathArr);#獲取長度用來分離出控制器和方法
    #獲取路徑
    $root = SERVER_ROOT . CONTROLLER_ROOT;
    for ($i=0; $i < $length-2; $i++) { 
        $root .= '/'.$pathArr[$i];
    }

    #判斷類檔案及類是否存在
    #命名規則為:
    #控制器檔案為小寫字母+'.php':welcome.php
    #控制器類名為首字母大寫+'_Controller':Welcome_Controller
    $class = $pathArr[$length-2];#$pathArr的最後元素為方法名
    $className = ucfirst($class) . '_Controller';
    $classFile = $root . '/' . $class . '.php';
    unset($class);#用完釋放,防止變數汙染
    if (!file_exists($classFile)) {
        exit('404');
    }else{
        include $classFile;#檔案存在,引入
        if (class_exists($className)) {
            $class = new $className();#類存在,例項化
        }else{
            exit('class not exist');#類不存在,報錯
        }
    }

    #獲取並呼叫function
    $functionStr = $pathArr[$length-1];
    #為了做到偽靜態,有時候方法後面我們加上'.html'或者'.php'
    $functionArr = explode('.', $functionStr);
    if (sizeof($functionArr)==2) {
        $function = $functionArr[0];
        $scriptType = $functionArr[1];
    }else{
        $function = $functionArr[0];
        $scriptType = 'undefined';
    }

    #獲得類和方法之後呼叫
    $class->$function();

因為我是在完成這個框架之後寫的該文,所以一定可用。
還是給出測試吧。
在controller下新建一個檔案 hello.php

    <?php 
    #測試用完即刪掉該檔案
    class Hello_Controller{
        public function world(){
            echo 'hello world';
        }
    }
 ?>

測試結果如圖:
測試結果

2)控制器載入檢視
前面已經做了URL到控制器和方法的路由,下面來做控制器載入檢視。
因為PHP是一種可嵌入到HTML的指令碼,所以我們可以直接在方法中include一個HTML,(好直白。。。)。同理,方法中所有在include之前宣告的變數都可以直接用,但這也是一個弊端,即所有的變數都可以在HTML中使用。所以我們將include封裝成一個方法,任何將要顯示在HTML頁面的變數都以引數的方式傳給該方法。
考慮到該方法可能會被多次呼叫,所以封裝為核心類的方法,這樣每次新建一個方法只要繼承核心類就可以呼叫。即在info_Controller.php中宣告一個loadView的方法,之後controller資料夾下所有的類都extends Info_Controller即可:

<?php 
    #核心類 info/core/Info_Controller.php
    class Info_Controller{
        public function loadView($view,$data=NULL){
            #拿到引數傳入的資料
            $data = $data;
            #所有檢視檔案都在VIEWS_ROOT中
            require_once(VIEWS_ROOT . "/$view");
        }
}
<?php 
    #使用者自定義類 info/controller/test/welcome.php
    class Welcome_Controller extends Info_Controller{
        public function hello(){
            $data['key'] = 'value';
            $this->loadView('welcome.html',$data);
        }
    }
}
<!-- 檢視檔案 /info/views/welcome.html -->
<html>
    <head>

    </head>
    <body>
        <?php var_dump($data);?>
        <h1>helloworld</h1>
    </body>
</html>

測試結果:
控制器載入檢視

3)控制器呼叫模型
模型層我們主要是用來進行資料庫操作。首先我們要連線資料庫。
連線資料庫的資訊,一般我們都放在單獨的配置檔案,連線的時候直接引入該檔案即可。

<?php 
    #/info/config/database.php
    $_DATABASE['DBdriver'] = 'mysql';
    $_DATABASE['host'] = 'localhost';
    $_DATABASE['port'] = '3306';
    $_DATABASE['username'] = 'root';
    $_DATABASE['password'] = 'root';
    $_DATABASE['database'] = 'bbs';

同2),我們肯能要多次進行資料庫操作,所以每次都去connect資料庫太繁瑣,這裡我們把連線資料庫的操作寫在核心model檔案:info_model.php的建構函式中,這樣之後我們每次新建一個模型的時候直接繼承核心model類即可。

<?php 
    #info/core/Info_Model.php
    #這裡我們使用PDO進行連線
    require_once(SERVER_ROOT . "/config/database.php");
    class Info_Model{
        function __construct(){
            #連結資料庫
            global $_DATABASE;#方法外的變數通過global引入
            $driver = $_DATABASE['DBdriver'];
            $host = $_DATABASE['host'];
            $port = $_DATABASE['port'];
            $username = $_DATABASE['username'];
            $password = $_DATABASE['password'];
            $database = $_DATABASE['database'];
            $this->db = new PDO("$driver:host=$host;dbname=$database;charset=utf8mb4",$username,$password);
            $this->db->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE,PDO::FETCH_ASSOC);#預設返回關聯陣列
            $this->db->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); #禁用prepared statements的模擬效果
        }
    }

每個model檔案中的類需要例項化之後才能使用。所以我們可以像2)中載入檢視一樣,在核心控制器中封裝一個載入模型的函式

<?php 
    #/info/core/Info_Controller.php
    class Info_Controller{
        #載入控制器
        public function loadView($view,$data=NULL){
            $data = $data;
            require_once(SERVER_ROOT . "/views/$view");
        }

        #載入模型
        public function loadModel($model,$alias=NULL){
            $modelFile = SERVER_ROOT . "/models/$model" . '.php';
            if (!file_exists($modelFile)) {
                exit('404');
            }else{
                require_once($modelFile);
                #參考CI,可以給呼叫的模型一個別名
                if ($alias) {
                    $this->$model=$this->$alias = new $model();
                }else{
                    $this->$model = new $model();
                }
            }
        }
    }

新建一個模型。

<?php 
    #/info/model/user_model.php
    class user_model extends Info_Model{
        #宣告一個讀取資料庫中所有使用者資料的方法
        #在此之前要在資料庫中新建一個使用者表‘user_info’並加入一些資料
        public function getAllUserInfo(){
            $sql = 'select * from user_info';
            $data = $this->db->query($sql)->fetchAll();
            return $data;
        }
    }

在自定義的控制器中載入該模型並呼叫上面宣告的方法

<?php 
    class Welcome_Controller extends Info_Controller{
        public function hello(){
            #載入模型並且給一個別名。
            $this->loadModel('user_model','user');
            #呼叫該模型的方法(獲取使用者資料)
            $userinfo = $this->user->getAllUserInfo();
            var_dump($userinfo);
        }
    }

測試結果:
控制器載入模型

相關推薦

一個自己MVC框架[php]

外包的活幹多了,總有一些小專案,這些小專案甚至不需要考慮安全。這時候用框架顯得浪費。自己手寫原生程式碼又有些不太習慣(框架用多了,有時候連基本的都忘了,不能忘本啊。。。) 許久不更的部落格。反正也沒多少人看,哈~就當給自己一個馬克,也希望能給一些剛踏入程式猿大

手把手教你一個自己的chrome擴充套件程式

手把手教你做一個自己的chrome擴充套件程式 [目錄] first.效果 1.收藏夾修改 (1).滑鼠移動到收藏夾上的動作效果 (2).收藏夾框 (3)百度搜索框功能 2.右上文字修改 3.背景圖片修改 4

C#一個自己的音樂播放器,包含基本常用功能

        前段時間老師佈置的作業是寫一個音樂播放器,現在播放器基本已經完成,在這裡總結一下這個過程中遇到的一些問題以及整個編寫思路,首先附幾張介面圖,功能比較簡易,大神們就請無視路過吧·····  軟體原始碼地址:https://downl

藉助baidu的jsonp介面,一個自己的候選片語件

先觀察 對介面進行提煉:https://sp0.baidu.com/5a1Fazu8AA54nxGko9WTAnF6hhy/su?wd=關鍵詞&cb=回撥函式 簡單測試一下: <!DOCTYPE html> <html> <head>

從 0 開始手寫一個 Spring MVC 框架,向高手進階

Spring框架對於Java後端程式設計師來說再熟悉不過了,以前只知道它用的反射實現的,但瞭解之後才知道有很多巧妙的設計在裡面。如果不看Spring的原始碼,你將會失去一次和大師學習的機會:它的程式碼規範,設計思想很值得學習。 我們程式設計師大部分人都是野路子,不懂什麼

程式設計師如何開始一個自己的 Side Project?

此係列文章我們開始聊一些軟體開發人員如何開始動手寫一些自己專案(Side Project)的思路與方法,以及過程中可能需要準備的知識,並分享一些相關的資源給大家。 1. 什麼是 Side Project Side Project 對應的中文是副業、業餘專案或小專案的意思。 其實大家目前接觸到的很多成熟的商業

6小時手把手帶你快速一個自己的Java學生資訊管理系統之Java學生資訊管理系統專案原始碼視訊教程

本視訊教程一共分為四個階段,每個階段都會是上一個階段的擴充套件,每一個階段的系統都可獨立作為一個完整的系統。第一階段是Java學生資訊管理系統,完成了學生資訊的管理、班級資訊的管理、教師資訊的管理、以及

一個自己的chrome瀏覽器外掛

因為前段時間聽室友說chrome沒有拖拽選中文字自動搜尋的功能,於是我突發奇想,響應毛主席的號召,自己動手,豐衣足食,於是很自然地想到了chrome的外掛,花了一天時間瞭解了下chrome外掛的工作原理,並寫了下面這個簡單的外掛。有點遺憾的是這個外掛只能實現選中

一個自己寫的PHP模板引擎

'; $stringHtml .= 'Error information: '; $stringHtml .= ''; $stringHtml .= $content; $stringHtml .= ''; $stringHtml .= ' '; exit($stringHtml); } } ?>

Python實戰1_1:一個自己的網頁

參加了Python實戰課程,此為第一節課的練習總結 成果 HTML程式碼 <!DOCTYPE html> <html lang="en"> <head

一個屬於自己PHPMVC框架(二)

第一篇文章已經把所需的目錄搭建好了,接下來的工作就是寫一些程式碼了 用編輯器開啟public/index.php檔案,寫上下面的程式碼 <?php define(DS, DIRECTORY_SEPARATOR); define(ROOT, dirna

一個屬於自己PHPMVC框架(一)

最近想做個PHP的個人部落格作為學習用,但是發現儘管把PHP函式用得很熟悉了,按照常規的辦法,寫一個頁面處理一個請求,僅僅一個部落格就可能有很多個頁面,而且php程式碼和html程式碼都結合的非常緊密,如果想要實現更換面板的功能,就顯得非常無力。在網上找了好多framework框架,但似乎又要開始學

PHP MVC框架基礎小白(自己動手寫一個PHP框架示例)

一個示例專案,具體展示了PHP,MVC模式框架開發的全過程本人小白一個,希望各位大神多多指教,由於教程文字過多而且不易解釋我直接將示例專案打包,下面附上鍊接各位對PHP框架學習可以借鑑專案內帶有其他方法和註釋,希望能對大家有所幫助

如何寫一個自己的渣渣PHP框架

.com 5% www tps tle title blank ref php 原文鏈接:https://www.opqnext.com/2017/01/18/%E5%A6%82%E4%BD%95%E5%86%99%E4%B8%80%E4%B8%AA%E8%87%AA%E5

一個自己寫的MVC框架

xml文件 ast target 實現類 讀取 能說 位置 加載 -i   也有個一周沒有更新博客了,其實我沒有偷懶,因為之前一直在看Spring源碼,所以想著去寫一個類Spring的框架,也沒有給自己定什麽高的要求,簡單實現MVC、AOP、IOC等功能就行。現在這個框架基

自己動手寫PHP-MVC框架(一)

自己動手模仿寫一個php的框架,首先是要明白原理,然後寫的話思路就比較清晰。 當前應用的基本組成是有一堆的資料夾和一個index的檔案組成         |-Conf       &n

怎麼樣寫一個自己的渣渣PHP框架(1)

專案地址 最近有時間,於是就想寫一個框架吧!這樣可以更好的瞭解整個框架是怎麼執行的,可以更好的理解MVC模式 面向物件模式等。寫的比較菜了。就當學習。哈哈哈! 進入正題: 實我還是建議初學者(特指已經學完PHP基礎語法,並且瞭解一些開源框架MVC,再加上composer的童鞋們)寫一個自

編寫自己PHP MVC框架

1 什麼是MVC MVC模式(Model-View-Controller)是軟體工程中的一種軟體架構模式。 MVC把軟體系統分為三個基本部分:模型(Model)、檢視(View)和控制器(Controller)。 PHP中MVC模式也稱Web MVC,從上世紀7

基於Java spring MVC框架 開發初步 ——以一個留言板為例

基於 Java spring MVC 框架 開發初步 ——以做一個留言板為例 作者: zccst 開發環境: 1 : java 1.6 2: mysql 5.1 3: resin 3.1 4: eclipse 3+ 開發環境配置:

使用PHP搭建自己MVC框架

模型(Model) “資料模型”(Model)用於封裝與應用程式的業務邏輯相關的資料以及對資料的處理方法。“模型”有對資料直接訪問的權力,例如對資料庫的訪問。“模型”不依賴“檢視”和“控制器”,也就是說,模型不關心它會被如何顯示或是如何被操作。但是模型中資料的變化一般會通過一種重新整理機制被公佈。為了實現