午夜剧场伦理_日本一道高清_国产又黄又硬_91黄色网战_女同久久另类69精品国产_妹妹的朋友在线

您的位置:首頁(yè)技術(shù)文章
文章詳情頁(yè)

使用PHP搭建自己的MVC框架

瀏覽:21日期:2022-09-13 10:41:27
一、什么是MVC

MVC模式(Model-View-Controller)是軟件工程中的一種軟件架構(gòu)模式,把軟件系統(tǒng)分為三個(gè)基本部分:模型(Model)、視圖(View)和控制器(Controller)。

MVC模式的目的是實(shí)現(xiàn)一種動(dòng)態(tài)的程序設(shè)計(jì),使后續(xù)對(duì)程序的修改和擴(kuò)展簡(jiǎn)化,并且使程序某一部分的重復(fù)利用成為可能。除此之外,此模式通過(guò)對(duì)復(fù)雜度的簡(jiǎn)化,使程序結(jié)構(gòu)更加直觀。軟件系統(tǒng)通過(guò)對(duì)自身基本部份分離的同時(shí)也賦予了各個(gè)基本部分應(yīng)有的功能。專業(yè)人員可以通過(guò)自身的專長(zhǎng)分組:

(控制器Controller)- 負(fù)責(zé)轉(zhuǎn)發(fā)請(qǐng)求,對(duì)請(qǐng)求進(jìn)行處理。(視圖View) – 界面設(shè)計(jì)人員進(jìn)行圖形界面設(shè)計(jì)。(模型Model) – 程序員編寫程序應(yīng)有的功能(實(shí)現(xiàn)算法等等)、數(shù)據(jù)庫(kù)專家進(jìn)行數(shù)據(jù)管理和數(shù)據(jù)庫(kù)設(shè)計(jì)(可以實(shí)現(xiàn)具體的功能)。

使用PHP搭建自己的MVC框架模型(Model)?“數(shù)據(jù)模型”(Model)用于封裝與應(yīng)用程序的業(yè)務(wù)邏輯相關(guān)的數(shù)據(jù)以及對(duì)數(shù)據(jù)的處理方法?!澳P汀庇袑?duì)數(shù)據(jù)直接訪問(wèn)的權(quán)力,例如對(duì)數(shù)據(jù)庫(kù)的訪問(wèn)?!澳P汀辈灰蕾嚒耙晥D”和“控制器”,也就是說(shuō),模型不關(guān)心它會(huì)被如何顯示或是如何被操作。但是模型中數(shù)據(jù)的變化一般會(huì)通過(guò)一種刷新機(jī)制被公布。為了實(shí)現(xiàn)這種機(jī)制,那些用于監(jiān)視此模型的視圖必須事先在此模型上注冊(cè),從而,視圖可以了解在數(shù)據(jù)模型上發(fā)生的改變。

視圖(View)?視圖層能夠?qū)崿F(xiàn)數(shù)據(jù)有目的的顯示(理論上,這不是必需的)。在視圖中一般沒(méi)有程序上的邏輯。為了實(shí)現(xiàn)視圖上的刷新功能,視圖需要訪問(wèn)它監(jiān)視的數(shù)據(jù)模型(Model),因此應(yīng)該事先在被它監(jiān)視的數(shù)據(jù)那里注冊(cè)。

控制器(Controller)?控制器起到不同層面間的組織作用,用于控制應(yīng)用程序的流程。它處理事件并作出響應(yīng)。“事件”包括用戶的行為和數(shù)據(jù)模型上的改變。

二、為什么要自己開(kāi)發(fā)MVC框架

網(wǎng)絡(luò)上有大量?jī)?yōu)秀的MVC框架可供使用,本教程并不是為了開(kāi)發(fā)一個(gè)全面的、終極的MVC框架解決方案,而是將它看作是一個(gè)很好的從內(nèi)部學(xué)習(xí)PHP的機(jī)會(huì),在此過(guò)程中,你將學(xué)習(xí)面向?qū)ο缶幊毯驮O(shè)計(jì)模式,并學(xué)習(xí)到開(kāi)放中的一些注意事項(xiàng)。

更重要的是,你可以完全控制你的框架,并將你的想法融入到你開(kāi)發(fā)的框架中。雖然不一定是做好的,但是你可以按照你的方式去開(kāi)發(fā)功能和模塊。

三、開(kāi)始開(kāi)發(fā)自己的MVC框架

在開(kāi)始開(kāi)發(fā)前,讓我們先來(lái)把項(xiàng)目建立好,假設(shè)我們建立的項(xiàng)目為todo,那么接下來(lái)的第一步就是把目錄結(jié)構(gòu)先設(shè)置好。

使用PHP搭建自己的MVC框架

雖然在這個(gè)教程中不會(huì)使用到上面的所有的目錄,但是為了以后程序的可拓展性,在一開(kāi)始就把程序目錄設(shè)置好使非常必要的。下面就具體說(shuō)說(shuō)每個(gè)目錄的作用:

application – 存放程序代碼config – 存放程序配置或數(shù)據(jù)庫(kù)配置db – 用來(lái)存放數(shù)據(jù)庫(kù)備份內(nèi)容library – 存放框架代碼public – 存放靜態(tài)文件scripts – 存放命令行工具tmp – 存放臨時(shí)數(shù)據(jù)

在目錄設(shè)置好以后,我們接下來(lái)就要來(lái)頂一下一些代碼的規(guī)范:

MySQL的表名需小寫并采用復(fù)數(shù)形式,如items,cars模塊名(Models)需首字母大寫,并采用單數(shù)模式,如Item,Car控制器(Controllers)需首字母大寫,采用復(fù)數(shù)形式并在名稱中添加“Controller”,如ItemsController, CarsController視圖(Views)采用復(fù)數(shù)形式,并在后面添加行為作為文件,如:items/view.php, cars/buy.php

上述的一些規(guī)則是為了能在程序鐘更好的進(jìn)行互相的調(diào)用。接下來(lái)就開(kāi)始真正的編碼了。

第一步將所有的的請(qǐng)求都重定向到public目錄下,解決方案是在todo文件下添加一個(gè).htaccesss文件,文件內(nèi)容為:

<IfModule mod_rewrite.c>RewriteEngine onRewriteRule ^$ public/ [L]RewriteRule (.*) public/$1 [L]</IfModule>

在我們把所有的請(qǐng)求都重定向到public目錄下以后,我們就需要將所有的數(shù)據(jù)請(qǐng)求都再重定向到public下的index.php文件,于是就需要在public文件夾下也新建一個(gè).htaccess文件,文件內(nèi)容為:

<IfModule mod_rewrite.c>RewriteEngine On#如果文件存在就直接訪問(wèn)目錄不進(jìn)行RewriteRuleRewriteCond %{REQUEST_FILENAME} !-f#如果目錄存在就直接訪問(wèn)目錄不進(jìn)行RewriteRuleRewriteCond %{REQUEST_FILENAME} !-d#將所有其他URL重寫到 index.php/URLRewriteRule ^(.*)$ index.php?url=$1 [PT,L]</IfModule>

這么做的主要原因有:

可以使程序有一個(gè)單一的入口,將所有除靜態(tài)程序以外的程序都重定向到index.php上;可以用來(lái)生成利于SEO的URL,想要更好的配置URL,后期可能會(huì)需要URL路由,這里先不做介紹了。

做完上面的操作,就應(yīng)該知道我們需要做什么了,沒(méi)錯(cuò)!在public目錄下添加index.php文件,文件內(nèi)容為:

<?php define(’DS’,DIRECTORY_SEPARATOR); define(’ROOT’,dirname(dirname(__FILE__))); $url = $_GET[’url’]; require_once(ROOT.DS.’library’.DS.’bootstrap.php’);

注意上面的PHP代碼中,并沒(méi)有添加PHP結(jié)束符號(hào)”?>”,這么做的主要原因是:對(duì)于只包含PHP代碼的文件,結(jié)束標(biāo)志(“?>”)最好不存在,PHP自身并不需要結(jié)束符號(hào),不添加結(jié)束符號(hào)可以很大程度上防止末尾被添加額外的注入內(nèi)容,讓程序更加安全。

在index.php中,我們對(duì)library文件夾下的bootstrap.php發(fā)起了請(qǐng)求,那么bootstrap.php這個(gè)啟動(dòng)文件中到底會(huì)包含哪些內(nèi)容呢?

<?php require_once(ROOT.DS.’config’.DS .’config.php’); require_once(ROOT.DS.’library’.DS .’shared.php’);

以上文件都可以直接在index.php文件中引用,我們這么做的原因是為了在后期管理和拓展中更加的方便,所以把需要在一開(kāi)始的時(shí)候就加載運(yùn)行的程序統(tǒng)一放到一個(gè)單獨(dú)的文件中引用。

先來(lái)看看config文件下的config .php文件,該文件的主要作用是設(shè)置一些程序的配置項(xiàng)及數(shù)據(jù)庫(kù)連接等,主要內(nèi)容為:

<?php # 設(shè)置是否為開(kāi)發(fā)狀態(tài) define(’DEVELOPMENT_ENVIRONMENT’,true); # 設(shè)置數(shù)據(jù)庫(kù)連接所需數(shù)據(jù) define(’DB_HOST’,’localhost’); define(’DB_NAME’,’todo’); define(’DB_USER’,’root’); define(’DB_PASSWORD’,’root’);

應(yīng)該說(shuō)config.php涉及到的內(nèi)容并不多,不過(guò)是一些基礎(chǔ)數(shù)據(jù)的一些設(shè)置,再來(lái)看看library下的共用文件shared.php應(yīng)該怎么寫。

<?php /* 檢查是否為開(kāi)發(fā)環(huán)境并設(shè)置是否記錄錯(cuò)誤日志 */ function setReporting(){if (DEVELOPMENT_ENVIRONMENT == 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’,ROOT.DS. ’tmp’ .DS. ’logs’ .DS. ’error.log’);} } /* 檢測(cè)敏感字符轉(zhuǎn)義(Magic Quotes)并移除他們 */ function stripSlashDeep($value){ $value = is_array($value) ? array_map(’stripSlashDeep’,$value) : stripslashes($value);return $value; } function removeMagicQuotes(){if (get_magic_quotes_gpc()) { $_GET = stripSlashDeep($_GET); $_POST = stripSlashDeep($_POST); $_COOKIE = stripSlashDeep($_COOKIE);} } /* 檢測(cè)全局變量設(shè)置(register globals)并移除他們 */ function unregisterGlobals(){ if (ini_get(’register_globals’)) { $array = array(’_SESSION’,’_POST’,’_GET’,’_COOKIE’,’_REQUEST’,’_SERVER’,’_ENV’,’_FILES’); foreach ($array as $value) { foreach ($GLOBALS[$value] as $key => $var) { if ($var === $GLOBALS[$key]) { unset($GLOBALS[$key]); } } } } } /* 主請(qǐng)求方法,主要目的拆分URL請(qǐng)求 */ function callHook() {global $url;$urlArray = array();$urlArray = explode('/',$url);$controller = $urlArray[0];array_shift($urlArray);$action = $urlArray[0];array_shift($urlArray);$queryString = $urlArray;$controllerName = $controller;$controller = ucwords($controller);$model = rtrim($controller, ’s’);$controller .= ’Controller’;$dispatch = new $controller($model,$controllerName,$action);if ((int)method_exists($controller, $action)) { call_user_func_array(array($dispatch,$action),$queryString);} else { /* 生成錯(cuò)誤代碼 */} } /* 自動(dòng)加載控制器和模型 */ function __autoload($className) {if (file_exists(ROOT . DS . ’library’ . DS . strtolower($className) . ’.class.php’)) { require_once(ROOT . DS . ’library’ . DS . strtolower($className) . ’.class.php’);} else if (file_exists(ROOT . DS . ’application’ . DS . ’controllers’ . DS . strtolower($className) . ’.php’)) { require_once(ROOT . DS . ’application’ . DS . ’controllers’ . DS . strtolower($className) . ’.php’);} else if (file_exists(ROOT . DS . ’application’ . DS . ’models’ . DS . strtolower($className) . ’.php’)) { require_once(ROOT . DS . ’application’ . DS . ’models’ . DS . strtolower($className) . ’.php’);} else { /* 生成錯(cuò)誤代碼 */} } setReporting(); removeMagicQuotes(); unregisterGlobals(); callHook();

接下來(lái)的操作就是在library中建立程序所需要的基類,包括控制器、模型和視圖的基類。

新建控制器基類為controller.class.php,控制器的主要功能就是總調(diào)度,具體具體內(nèi)容如下:

<?php class Controller {protected $_model;protected $_controller;protected $_action;protected $_template;function __construct($model, $controller,$action) { $this->_controller = $controller; $this->_action = $action; $this->_model = $model; $this->$model =& new $model; $this->_template =& new Template($controller,$action);}function set($name,$value) { $this->_template->set($name,$value);}function __destruct() { $this->_template->render();} }

新建控制器基類為model.class.php,考慮到模型需要對(duì)數(shù)據(jù)庫(kù)進(jìn)行處理,所以可以新建一個(gè)數(shù)據(jù)庫(kù)基類sqlquery.class.php,模型去繼承sqlquery.class.php。

新建sqlquery.class.php,代碼如下:

<?php class SQLQuery {protected $_dbHandle;protected $_result;/** 連接數(shù)據(jù)庫(kù) **/function connect($address, $account, $pwd, $name) { $this->_dbHandle = @mysql_connect($address, $account, $pwd); if ($this->_dbHandle != 0) { if (mysql_select_db($name, $this->_dbHandle)) { return 1; }else { return 0; } }else { return 0; } }/** 中斷數(shù)據(jù)庫(kù)連接 **/function disconnect() { if (@mysql_close($this->_dbHandle) != 0) { return 1; } else { return 0; }}/** 查詢所有數(shù)據(jù)表內(nèi)容 **/function selectAll() { $query = ’select * from `’.$this->_table.’`’; return $this->query($query);}/** 查詢數(shù)據(jù)表指定列內(nèi)容 **/function select($id) { $query = ’select * from `’.$this->_table.’` where `id` = ’’.mysql_real_escape_string($id).’’’; return $this->query($query, 1);}/** 自定義SQL查詢語(yǔ)句 **/function query($query, $singleResult = 0) { $this->_result = mysql_query($query, $this->_dbHandle); if (preg_match('/select/i',$query)) { $result = array(); $table = array(); $field = array(); $tempResults = array(); $numOfFields = mysql_num_fields($this->_result); for ($i = 0; $i < $numOfFields; ++$i) { array_push($table,mysql_field_table($this->_result, $i)); array_push($field,mysql_field_name($this->_result, $i)); } while ($row = mysql_fetch_row($this->_result)) { for ($i = 0;$i < $numOfFields; ++$i) {$table[$i] = trim(ucfirst($table[$i]),'s');$tempResults[$table[$i]][$field[$i]] = $row[$i]; } if ($singleResult == 1) { mysql_free_result($this->_result); return $tempResults; } array_push($result,$tempResults); } mysql_free_result($this->_result); return($result); } } /** 返回結(jié)果集行數(shù) **/function getNumRows() { return mysql_num_rows($this->_result);}/** 釋放結(jié)果集內(nèi)存 **/function freeResult() { mysql_free_result($this->_result);} /** 返回MySQL操作錯(cuò)誤信息 **/ function getError() { return mysql_error($this->_dbHandle); } }

新建model.class.php,代碼如下:

<?php class Model extends SQLQuery{protected $_model;function __construct() { $this->connect(DB_HOST,DB_USER,DB_PASSWORD,DB_NAME); $this->_model = get_class($this); $this->_table = strtolower($this->_model).'s';}function __destruct() {} }

新建視圖基類為template.class.php,具體代碼如下:

<?php class Template { protected $variables = array(); protected $_controller; protected $_action; function __construct($controller,$action) { $this->_controller = $controller; $this->_action =$action; } /* 設(shè)置變量 */ function set($name,$value) { $this->variables[$name] = $value; } /* 顯示模板 */ function render() { extract($this->variables); if (file_exists(ROOT.DS. ’application’ .DS. ’views’ .DS. $this->_controller .DS. ’header.php’)) { include(ROOT.DS. ’application’ .DS. ’views’ .DS. $this->_controller .DS. ’header.php’); } else { include(ROOT.DS. ’application’ .DS. ’views’ .DS. ’header.php’); } include (ROOT.DS. ’application’ .DS. ’views’ .DS. $this->_controller .DS. $this->_action . ’.php’); if (file_exists(ROOT.DS. ’application’ .DS. ’views’ .DS. $this->_controller .DS. ’footer.php’)) { include (ROOT.DS. ’application’ .DS. ’views’ .DS. $this->_controller .DS. ’footer.php’); } else { include (ROOT.DS. ’application’ .DS. ’views’ .DS. ’footer.php’); }} }

做完了以上這么多操作,基本上整個(gè)MVC框架已經(jīng)出來(lái)了,下面就該制作我們的站點(diǎn)了。我們要做的站點(diǎn)其實(shí)很簡(jiǎn)單,一個(gè)ToDo程序。

首先是在我們的/application/controller/ 目錄下面新建一個(gè)站點(diǎn)控制器類為ItemsController,命名為itemscontroller.php,內(nèi)容為:

<?php class ItemsController extends Controller { function view($id = null,$name = null) { $this->set(’title’,$name.’ - My Todo List App’); $this->set(’todo’,$this->Item->select($id)); } function viewall() { $this->set(’title’,’All Items - My Todo List App’); $this->set(’todo’,$this->Item->selectAll()); } function add() { $todo = $_POST[’todo’]; $this->set(’title’,’Success - My Todo List App’); $this->set(’todo’,$this->Item->query(’insert into items (item_name) values (’’.mysql_real_escape_string($todo).’’)’)); } function delete($id) { $this->set(’title’,’Success - My Todo List App’); $this->set(’todo’,$this->Item->query(’delete from items where id = ’’.mysql_real_escape_string($id).’’’)); } }

接下來(lái)就是先建站點(diǎn)的模型,在我們的/application/model/ 目錄下面先建一個(gè)站點(diǎn)模型類為Item,內(nèi)容直接繼承Model,代碼如下:

<?phpclass Item extends Model {}

最后一步是設(shè)置我們站點(diǎn)的視圖部分,我們現(xiàn)在/application/views/目錄下新建一個(gè)items的文件夾,再在items文件夾下建立與控制器重Action相同的文件,分別為view.php,viewall.php,add.php,delete.php,考慮到這么頁(yè)面中可能需要共用頁(yè)首和頁(yè)尾,所以再新建兩個(gè)文件,命名為header.php,footer.php,每個(gè)文件的代碼如下:

view.php文件:查看單條待處理事務(wù)

<h2><?php echo $todo[’Item’][’item_name’]?></h2><a href='http://www.leifengta.com.cn/items/delete/<?php echo $todo[’Item’][’id’]?>'><span>Delete this item</span></a>

viewall.php文件:查看所有待處理事務(wù)

<form action='../items/add' method='post'> <input type='text' value='I have to...' onclick='this.value=’’' name='todo'> <input type='submit' value='add'></form><br/><br/><?php $number = 0?><?php foreach ($todo as $todoitem):?> <a href='http://www.leifengta.com.cn/items/view/<?php echo $todoitem[’Item’][’id’]?>/<?php echo strtolower(str_replace(' ','-',$todoitem[’Item’][’item_name’]))?>'><span> <?php echo ++$number?> <?php echo $todoitem[’Item’][’item_name’]?></span> </a><br/><?php endforeach?>

add.php文件:添加待處理事務(wù)

<a href='http://www.leifengta.com.cn/items/viewall'>Todo successfully added. Click here to go back.</a><br/>

delete.php文件:刪除事務(wù)

<a href='http://www.leifengta.com.cn/items/viewall'>Todo successfully deleted. Click here to go back.</a><br/>

header.php:頁(yè)首文件

<html><head><title><?php echo $title?></title><style>.item {width:400px;}input {color:#222222;font-family:georgia,times;font-size:24px;font-weight:normal;line-height:1.2em;color:black;}a {color:#222222;font-family:georgia,times;font-size:24px;font-weight:normal;line-height:1.2em;color:black;text-decoration:none;}a:hover {background-color:#BCFC3D;}h1 {color:#000000;font-size:41px;letter-spacing:-2px;line-height:1em;font-family:helvetica,arial,sans-serif;border-bottom:1px dotted #cccccc;}h2 {color:#000000;font-size:34px;letter-spacing:-2px;line-height:1em;font-family:helvetica,arial,sans-serif;}</style></head><body><h1>My Todo-List App</h1>

footer.php:頁(yè)尾文件

</body></html>

當(dāng)然還有一個(gè)必不可少的操作就是在數(shù)據(jù)中中建立一張表,具體代碼如下:

CREATE TABLE IF NOT EXISTS `items` ( `id` int(11) NOT NULL AUTO_INCREMENT, `item_name` varchar(255) NOT NULL, PRIMARY KEY (`id`)) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=17 ;

至此一個(gè)使用MVC開(kāi)發(fā)的網(wǎng)站就開(kāi)發(fā)完成了,你現(xiàn)在可以通過(guò)訪問(wèn)http://localhost/todo/items/viewall?查看新建的站點(diǎn)。

標(biāo)簽: PHP
相關(guān)文章:
主站蜘蛛池模板: 亚洲精品亚洲 | 湖南良妇3p自拍 | 91久久久久久久久久久 | 天天操综合 | 黑丝白浆 | 天堂岛av | 四虎免费在线 | 欧美日韩午夜 | 男人资源av | 国产三级观看 | 午夜男人天堂 | 欧美网站在线观看 | 四虎永久免费在线观看 | 亚洲激情视频网站 | 99久久精品国产一区二区三区 | 性天堂av| 亚洲国产高清视频 | a级黄色免费视频 | 亚洲精品中字 | 亚洲一二三视频 | 男人的天堂视频网站 | 在线观看亚洲大片短视频 | 2020av| 日韩一区二区三区免费观看 | 黄色av一区二区三区 | 一区二区三区亚洲视频 | 亚洲欧洲天堂 | 日韩一区二区高清 | 成人av影院 | 久久久久久国产精品三级玉女聊斋 | 深夜国产福利 | 福利社午夜影院 | 精品久久99| 黄色天天影视 | 爱情与灵药在线 | 夜夜狠狠擅视频 | 日韩一区二区在线播放 | 国产97超碰 | 亚洲黄色免费网站 | 亚洲精品国产精品乱码不99 | 青青草日本 |