MVC框架淺析(基於PHP)
MVC全名是Model View Controller,是模型(model)-視圖(view)-控制器(controller)的縮寫,一種軟件設計典範,用一種業務邏輯、數據、界面 顯示分離的方法組織代碼,將業務邏輯彙集到一個部件裏面,在改進和個性化定製界面及用戶交互的同時,不須要從新編寫業務邏輯。MVC被獨特的發展起來用於 映射傳統的輸入、處理和輸出功能在一個邏輯的圖形化用戶界面的結構中。php
一.MVC概念
MVC 是一種使用 MVC(Model View Controller 模型-視圖-控制器)設計建立 Web 應用程序的模式,它們各自處理本身的任務:
MVC 模式同時提供了對 HTML、CSS 和 JavaScript 的徹底控制。css
Model(模型)是應用程序中用於處理應用程序數據邏輯的部分。
一般模型對象負責在數據庫中存取數據。
View(視圖)是應用程序中處理數據顯示的部分。
一般視圖是依據模型數據建立的。
Controller(控制器)是應用程序中處理用戶交互的部分。
一般控制器負責從視圖讀取數據,控制用戶輸入,並向模型發送數據。html
MVC 分層有助於管理複雜的應用程序,由於您能夠在一個時間內專門關注一個方面。例如,您能夠在不依賴業務邏輯的狀況下專一於視圖設計。同時也讓應用程序的測試更加容易。
MVC 分層同時也簡化了分組開發。不一樣的開發人員可同時開發視圖、控制器邏輯和業務邏輯。mysql
有不少程序員每每認爲MVC是一種設計模式。實際上MVC是一種框架模式。框架一般是代碼重用,而設計模式是設計重用,架構則介於二者之間,部分代碼重用,部分設計重用,有時分析也可重用。jquery
簡而言之:框架是大智慧,用來對軟件設計進行分工;設計模式是小技巧,對具體問題提出解決方案,以提升代碼複用率,下降耦合度。程序員
二.MVC理解
面向對象的思惟sql
獲取和描述系統的用戶需求;thinkphp
識別角色和用例,畫UseCase;數據庫
根據功能從用例圖中找三種類型類:實體類、邊界類和控制類;將全部找到的三種類集中綜合在一塊兒獲得三大模型:實體模型、視圖模型、邏輯模型。實際上對應着MVC。進而進行WEB建模。apache
三.MVC實踐
MVC是一種框架模式,只有在實例中才能更好的理解MVC。本文基於ThinkPHP3.2.3的MVC框架,實現一個簡單的留言板系統。
1. ThinkPHP3.2.3
ThinkPHP是一個快速、兼容並且簡單的輕量級國產PHP開發框架,遵循Apache2開源協議發佈,從Struts結構移植過來並作了改進和完善, 同時也借鑑了國外不少優秀的框架和模式,使用面向對象的開發結構和MVC,融合了Struts的思想和TagLib(標籤庫)、RoR的ORM映射和 ActiveRecord模式。
ThinkPHP能夠支持windows/Unix/Liunx等服務器環境,支持MySql、PgSQL、Sqlite以及PDO等多種數據庫。做爲一 個總體開發解決方案,它包含了底層架構、兼容處理、基類庫、數據庫訪問層、模板引擎、緩存機制、插件機制、角色認證、表單處理等經常使用的組件,而且對於跨版 本、跨平臺和跨數據庫移植都比較方便。
ThinkPHP3.2.3是最新版本. 獲取地址:http://www.thinkphp.cn/,(初學建議下載完版)。
ThinkPHP須要集成環境,這裏用Wampserver。Wamp就是Windows Apache Mysql PHP集成安裝環境,即在window下的apache、php和mysql的服務器軟件。PHP擴展、Apache模塊,開啓/關閉鼠標點點就搞定,再 也不用親自去修改配置文件了,WAMP它會去作。
獲取地址:http://www.wampserver.com/en/
2. 需求分析和原型設計
2.1 系統需求
用戶進行註冊,而後登錄系統,進行留言。
2.2 原型設計
Axure RP 能幫助網站需求設計者,快捷而簡便的建立 基於目錄組織的原型文檔、功能說明、交互界面以及帶註釋的wireframe網頁,並可自動生成用於演示的網頁文件和word文檔,以提供演示與開發。
獲取地址:http://www.axure.com/
2.2.1 登錄頁面:
2.2.2 註冊頁面:
2.2.3 系統頁面:
2.3 功能設計
註冊模塊:註冊用戶
登陸模塊:登陸 退出
留言模塊:提交留言信息 顯示留言信息
2.4 數據庫設計
2.4.1 分析:
用戶表:用戶名、密碼、性別
留言表:留言題目、留言內容、附件名、留言時間
用戶表與留言表之間是一對多的關係,須要在留言表中設置外鍵。
2.4.2 設計:
用戶表(tp_user)
字段 |
類型 |
notnull |
默認值 |
備註 |
id |
Int |
notnull |
|
主鍵 自增 |
username |
varchar(30) |
|
‘’ |
用戶名 |
password |
char(32) |
|
‘’ |
密碼 |
sex |
tyint |
notnull |
1 |
性別:1表明男 0 表明0 |
留言表(tp_message)
字段 |
類型 |
notnull |
默認值 |
備註 |
id |
Int |
notnull |
|
主鍵 自增 |
title |
varchar(60) |
|
‘’ |
題目 |
content |
test |
|
‘’ |
內容 |
filename |
varchar(30) |
notnull |
1 |
附件名 |
time |
int |
|
|
時間:時間戳格式 |
uid |
int |
|
|
外鍵:用戶表中的id |
3. ThinkPHP設計思想與目錄文件
在Wampserver安裝地址下的www文件夾下新建項目think_message。將ThinkPHP_3.2.3_full.zip解壓放到think_message中。
在瀏覽器中,打開項目think_message,ThinkPHP會自動在Application文件夾下建立Home文件夾,它是前臺模塊;一樣咱們 能夠在Application下建立後臺模塊,本留言系統暫時不創建後臺模塊。到此ThinkPHP環境基本搭建完畢。
3.1 解壓縮能夠看到初始的目錄結構以下:
3.2 ThinkPHP內核 框架設計
3.3 模塊設計
每一個模塊是相對獨立的,其目錄結構以下:
之後咱們主要在Controller、Model和View三個文件下實施項目,即MVC。
4. 實施項目
本項目用sublime編輯器,進行代碼編輯。
4.1 打開phpmyadmin,創建數據庫messge
新建tp_user表和tp_message表,按照數據庫設計對應鍵入。注意:整理項Collation選擇 utf8- general-ci。
4.2 鏈接數據庫
Application->Common->Conf下的config.php,鍵入一下代碼:
//
數據庫類型 'DB_HOST' => 'localhost', // 服務器地址 'DB_NAME' => 'message', // 數據庫名 'DB_USER' => 'root', // 用戶名 'DB_PWD' => '', // 密碼 'DB_PORT' => 3306, // 端口 'DB_PREFIX' => 'tp_', // 數據庫表前綴 'DB_CHARSET'=> 'utf8', // 字符集
4.3 編碼
在根目錄下Public下創建Css、Js、Images和Uploads四個文件夾,分別用於存儲系統的css代碼、js代碼、系統所用的圖片資源和用戶上傳的文件資源。
根據功能設計,咱們首先在Application->Home->Controller,創建三個控制 器:RegisterController.class.php、LoginController.class.php、 MessageController.class.php;以及創建IndexController.class.php控制器,系統默認進入的控制器。 之後有須要咱們再添加。控制器裏面是函數,處理不一樣邏輯需求。
根據所建控制器及要顯示的頁面,在Application->Home->View下,分別建立Index(系統頁面)、Register(註冊頁面)和Login(登錄頁面)文件夾,用於原型設計的三個頁面顯示。
4.3.1 註冊
功能:實現用戶註冊
V
註冊須要顯示註冊頁面,咱們在Home->View->Register文件夾下建立reg.html用於顯示註冊頁面。代碼以下:
DOCTYPE html
> <html> <head> <meta http-equiv="content-type" content="text/html; charset=utf-8"> <title>註冊</title> <load href="__PUBLIC__/Css/Home/reg.css" /> <load href="__PUBLIC__/Js/jquery.js"/> <load href="__PUBLIC__/Css/basic.css" /> <script>functionvar= Array(); $(input[name="username"]).blur((){ username$().val(); $.get(__URL__/checkName,{username:username},(data){ (data''''=; $(input[name="username"]).after(<p id="umessage" style="color:red">該用戶名已經註冊</p>); }{ error[username]0; $(#umessage).remove(); } }); }); 提交表單 ''functionif''==){ false; }{ $(form[name="myForm"]).submit(); } }); }); </script> </head> <body> <form action='__URL__/doReg' method='post' name='myForm'> 用 戶 名:<input type='text' name='username'/><br/> 密 碼:<input type='password' name='password'/><br/> 確認密碼:<input type='password' name='repassword'/><br/> 性 別:<input type='radio' name='sex' value='1' class='radio'/>男 <input type='radio' name='sex' value='0' class='radio'/>女<br/> 驗 證 碼:<input type='text' name='code'/> <img src='__MODULE__/Public/code' onclick="this.src=this.src+'?'+Math.random()"/> <br/> <img src='__PUBLIC__/Images/register.gif' class='register'/> <img src='__PUBLIC__/Images/reset.gif' class='reset'/> </form> </body> </html>
C
RegisterController.class.php控制器代碼以下:
php namespace Home\Controller;
use Think\Controller; class RegisterController extends Controller { //顯示註冊頁面 public function reg(){ $this->display(); } //檢查用戶是否註冊過 public function checkName(){ $username=$_GET['username']; $user=M('User'); $where['username']=$username; $count=$user->where($where)->count(); if($count){ echo '不容許'; }else{ echo '容許'; } } //註冊 public function doReg(){ $user=D('User'); if(!$user->create()){ $this->error($user->getError()); } $lastId=$user->add(); if($lastId){ $this->redirect('Index/index'); }else{ $this->error('用戶註冊失敗'); } } } ?>
創建了PublicController.class.php控制器,設置驗證碼的屬性。代碼以下:
php namespace Home\Controller;
use Think\Controller; class PublicController extends Controller { public function code(){ $Verify = new \Think\Verify(); $Verify->fontSize = 16; $Verify->length = 4; $Verify->imageW = 130; $Verify->imageH = 30; $Verify->entry(); } } ?>
M
前臺的驗證只是提供用戶體驗,安全仍是要後臺進行驗證。TinkPHP實現自動驗證,在Home->View->Model下,新建UserModel.class.php模型,進行自動驗證。代碼以下:
php namespace Home\Model;
use Think\Model; class UserModel extends Model{ protected $_validate=array( array('code','require','驗證碼必須填寫!'), array('code','checkCode','驗證碼錯誤!',0,'callback',1), array('username','require','用戶必須填寫!'), array('username','','用戶已經存在',0,'unique',1), array('username','/^\w{6,}$/','用戶名必須6個字母以上',0,'regex',1), array('repassword','password','確認密碼不正確',0,'confirm'), ); protected function checkCode($code){ function check_verify($code, $id = ''){ $verify = new \Think\Verify(); return $verify->check($code, $id); } if(!check_verify($code,$id = '')){ return false; }else{ return true; } } } ?>
4.3.2 登錄
功能:實現用戶登錄
V
登錄頁面須要顯示,咱們在Home->View->Login文件夾下建立login.html用於顯示註冊頁面。代碼以下:
DOCTYPE html
> <html lang="en"> <head> <meta charset="UTF-8"> <title>Login</title> <load href="__PUBLIC__/Css/basic.css" /> <load href="__PUBLIC__/Css/Home/login.css" /> <load href="__PUBLIC__/Js/jquery.js"/> <script>function''function'').submit(); }); $(img[class="register"]).click((){ window.location''; }); }); </script> </head> <body> <form action='__URL__/doLogin' method='post' name='myForm'> 用戶名:<input type='text' name='username'/><br/> 密 碼:<input type='password' name='password'/><br/> 驗證碼:<input type='text' name='code'/> <img src='__MODULE__/Public/code' onclick="this.src=this.src+'?'+Math.random()"/><br/> <img src='__PUBLIC__/Images/login.gif' title='login' class='submit'/> <img src='__PUBLIC__/Images/register.gif' class='register'/> </form> </body> </html>
C
LoginController.class.php控制器代碼以下:
php namespace Home\Controller; use Think\Controller; class LoginController extends Controller { //
顯示登錄頁面 public function index(){ $this->display(); } public function doLogin(){ //接受值 //判斷用戶在數據庫中是否存在 //存在 容許登陸 //不存在 顯示錯誤信息 $username=$_POST['username']; $password=$_POST['password']; $code=$_POST['code']; function check_verify($code, $id = ''){ $verify = new \Think\Verify(); return $verify->check($code, $id); } if(!check_verify($code,$id = '')){ $this->error('驗證碼輸入錯誤!'); } $user=M('User'); $where['username']=$username; $where['password']=$password; $arr=$user->field('id')->where($where)->find(); if($arr){ $_SESSION['username']=$username; $_SESSION['id']=$arr['id']; $this->success('用戶登陸成功',U('Index/index')); }else{ $this->error('該用戶不存在'); } } } ?>
4.3.3 系統頁面
功能:實現用戶用戶留言
V
系統頁面使用frameset將整個頁面分爲3部分top,left,right,咱們在Home->View->Index文件夾下建立index.html、top.html、left.html,right.html。代碼以下:
index.html。代碼以下:
DOCTYPE html
> <html lang="en"> <head> <meta charset="UTF-8"> <title>Index</title> </head> <frameset rows='20%,*'> <frame src='__URL__/top' name='top'/> <frameset cols='50%,50%'> <frame src='__URL__/left' name='left'/> <frame src='__URL__/right' name='right'/> </frameset> </frameset> </html>
top.html,用於顯示歡迎。代碼以下:
DOCTYPE html
> <html lang="en"> <head> <meta charset="UTF-8"> <title>top</title> </head> <body> <p>歡迎你 <strong>{$Think.session.username}</strong> !<a href='__APP__/Home/Login/doLogout' target='_top'>退出</a></p> <h1 align="center">ThinkPHP留言板系統</h1> </body> </html>
left.html,用於顯示全部的留言內容。代碼以下:
DOCTYPE html
> <html lang="en"> <head> <meta charset="UTF-8"> <title>Left</title> </head> <body> <foreach name='list' item='vo'> 留言題目:{$vo.title}<br/> <p>留言內容:</p>{$vo.content}<br/> 附件名:{$vo.filename}<br/> {$vo.username} {$vo.time|date='Y/m/d H:i:s',###}<br/> <hr/> </foreach> {$show} </body> </html>
right.html,用於提交留言。代碼以下:
DOCTYPE html
> <html lang="en"> <head> <meta charset="UTF-8"> <title>Right</title> </head> <body> <form action='__MODULE__/Message/doMess' method='post' enctype='multipart/form-data'> 留言題目:<input type='text' name='title'/><br/> 留言內容:<textarea name='content'></textarea><br/> 附 件:<input type='file' name='filename'/><br/> <input type='submit' value='提交留言'/> </form> </body> </html>
C
IndexController.class.php控制器,用於頁面的總體顯示。代碼以下:
php namespace Home\Controller;
use Think\Controller; class IndexController extends CommonController { public function index(){ $this->display(); } public function top(){ $this->display(); } public function left(){ $message=D('Message'); $count=$message->count();//獲取數據的總數 $Page = new \Think\Page($count,3);// 實例化分頁類 傳入總記錄數和每頁顯示的記錄數(3) $show = $Page->show();// 分頁顯示輸出 $arr=$message->relation(true)->order('time desc')->limit($Page->firstRow.','.$Page->listRows)->select(); $this->assign('list',$arr); $this->assign('show',$show); $this->display(); } public function right(){ $this->display(); } } ?>
MessageController.class.php控制器,用於留言的邏輯控制。代碼以下:
php namespace Home\Controller;
use Think\Controller; class MessageController extends Controller { public function doMess(){ $upload = new \Think\Upload();// 實例化上傳類 $upload->rootPath = './Public/Uploads/';//設置附件上傳目錄 $info = $upload->upload(); if(!$info) {// 上傳錯誤提示錯誤信息 $this->error($upload->getError()); }else{// 上傳成功 獲取上傳文件信息 foreach($info as $file){ // $savename=$file['savepath'].$file['savename']; $savename=$file['savename']; } } $message=D('Message'); $message->create(); $message->filename=$savename; // $message->time=time(); // $message->uid=$_SESSION['id']; $lastId=$message->add(); if($lastId){ $this->success('留言成功'); }else{ $this->error('留言失敗'); } } } ?>
M
TinkPHP實現自動完成,並實現tp_user表和tp_messgae表的關聯取字段值,在Home->View->Model下,新建MessageModel.class.php模型,進行自動驗證。代碼以下:
php namespace Home\Model;
use Think\Model\RelationModel; class MessageModel extends RelationModel{ protected $_auto=array( array('time','time',1,'function'), array('uid','getId',1,'callback'), ); protected $_link=array( 'User'=> array( 'mapping_type' => self::BELONGS_TO, 'class_name'=>'User', 'foreign_key'=>'uid', 'mapping_name'=>'user', 'mapping_fields'=>'username', 'as_fields'=>'username', ), ); protected function getId(){ return $_SESSION['id']; } } ?>
爲了網站安全
必須進行登陸才能進入任何一個頁面,添加CommonController.class.php控制器。代碼以下:
php namespace Home\Controller;
use Think\Controller; class CommonController extends Controller { Public function _initialize(){ // 初始化的時候檢查用戶權限 if(!isset($_SESSION['username']) || $_SESSION['username']==''){ $this->redirect('Login/login'); } } } ?>
最終的文件目錄以下:
至此基於PHP的MVC思想創建的留言系統已完成。
摘自:http://www.cnblogs.com/jingwhale/p/4303684.html