<delect id="sj01t"></delect>
  1. <em id="sj01t"><label id="sj01t"></label></em>
  2. <div id="sj01t"></div>
    1. <em id="sj01t"></em>

            <div id="sj01t"></div>
            php語言

            如何使用PHP開發自己的MVC框架

            時間:2025-05-21 14:45:30 php語言 我要投稿
            • 相關推薦

            如何使用PHP開發自己的MVC框架

              MVC模式(Model-View-Controller)是軟件工程中的一種軟件架構模式,把軟件系統分為三個基本部分:模型(Model)、視圖(View)和控制器(Controller)。下面是小編為大家帶來的如何使用PHP開發自己的MVC框架的知識,歡迎閱讀。

              一、什么是MVC

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

              MVC模式的目的是實現一種動態的程序設計,使后續對程序的修改和擴展簡化,并且使程序某一部分的重復利用成為可能。除此之外,此模式通過對復雜度的簡化,使程序結構更加直觀。軟件系統通過對自身基本部份分離的同時也賦予了各個基本部分應有的功能。專業人員可以通過自身的專長分組:

              (控制器Controller)- 負責轉發請求,對請求進行處理。

              (視圖View) – 界面設計人員進行圖形界面設計。

              (模型Model) – 程序員編寫程序應有的功能(實現算法等等)、數據庫專家進行數據管理和數據庫設計(可以實現具體的功能)。

              模型(Model) “數據模型”(Model)用于封裝與應用程序的業務邏輯相關的數據以及對數據的處理方法。“模型”有對數據直接訪問的權力,例如對數據庫的訪問。“模型”不依賴“視圖”和“控制器”,也就是說,模型不關心它會被如何顯示或是如何作。但是模型中數據的變化一般會通過一種刷新機制被公布。為了實現這種機制,那些用于監視此模型的視圖必須事先在此模型上注冊,從而,視圖可以了解在數據模型上發生的改變。

              視圖(View) 視圖層能夠實現數據有目的的顯示(理論上,這不是必需的)。在視圖中一般沒有程序上的邏輯。為了實現視圖上的刷新功能,視圖需要訪問它監視的數據模型(Model),因此應該事先在被它監視的數據那里注冊。

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

              二、為什么要自己開發MVC框架

              網絡上有大量優秀的MVC框架可供使用,本教程并不是為了開發一個全面的、終極的MVC框架解決方案,而是將它看作是一個很好的從內部學習PHP的機會,在此過程中,你將學習面向對象編程和設計模式,并學習到開放中的一些注意事項。

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

              三、開始開發自己的MVC框架

              在開始開發前,讓我們先來把項目建立好,假設我們建立的項目為todo,那么接下來的第一步就是把目錄結構先設置好。

              todo

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

              application – 存放程序代碼

              config – 存放程序配置或數據庫配置

              db – 用來存放數據庫備份內容

              library – 存放框架代碼

              public – 存放靜態文件

              scripts – 存放命令行工具

              tmp – 存放臨時數據

              在目錄設置好以后,我們接下來就要來頂一下一些代碼的規范:

              MySQL的表名需小寫并采用復數形式,如items,cars

              模塊名(Models)需首字母大寫,并采用單數模式,如Item,Car

              控制器(Controllers)需首字母大寫,采用復數形式并在名稱中添加“Controller”,如ItemsController, CarsController

              視圖(Views)采用復數形式,并在后面添加行為作為文件,如:items/view.php, cars/buy.php

              上述的一些規則是為了能在程序鐘更好的進行互相的調用。接下來就開始真正的編碼了。

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

              &lt;IfModule mod_rewrite.c&gt;

              RewriteEngine on

              RewriteRule    ^$    public/    [L]

              RewriteRule    (.*) public/$1    [L]

              &lt;/IfModule&gt;

              在我們把所有的請求都重定向到public目錄下以后,我們就需要將所有的數據請求都再重定向到public下的index.php文件,于是就需要在public文件夾下也新建一個.htaccess文件,文件內容為:

              &lt;IfModule mod_rewrite.c&gt;

              RewriteEngine On

              #如果文件存在就直接訪問目錄不進行RewriteRule

              RewriteCond %{REQUEST_FILENAME} !-f

              #如果目錄存在就直接訪問目錄不進行RewriteRule

              RewriteCond %{REQUEST_FILENAME} !-d

              #將所有其他URL重寫到 index.php/URL

              RewriteRule ^(.*)$ index.php?url=$1 [PT,L]

              &lt;/IfModule&gt;

              這么做的主要原因有:

              可以使程序有一個單一的入口,將所有除靜態程序以外的程序都重定向到index.php上;

              可以用來生成利于SEO的URL,想要更好的配置URL,后期可能會需要URL路由,這里先不做介紹了。

              做完上面的操作,就應該知道我們需要做什么了,沒錯!在public目錄下添加index.php文件,文件內容為:

              &lt;?php

              define('DS',DIRECTORY_SEPARATOR);

              define('ROOT',dirname(dirname(__FILE__)));

              $url = $_GET['url'];

              require_once(ROOT.DS.'library'.DS.'bootstrap.php');

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

              在index.php中,我們對library文件夾下的bootstrap.php發起了請求,那么bootstrap.php這個啟動文件中到底會包含哪些內容呢?

              &lt;?php

              require_once(ROOT.DS.'config'.DS .'config.php');

              require_once(ROOT.DS.'library'.DS .'shared.php');

              以上文件都可以直接在index.php文件中引用,我們這么做的原因是為了在后期管理和拓展中更加的方便,所以把需要在一開始的時候就加載運行的程序統一放到一個單獨的文件中引用。

              先來看看config文件下的config .php文件,該文件的主要作用是設置一些程序的配置項及數據庫連接等,主要內容為:

              &lt;?php

              # 設置是否為開發狀態

              define('DEVELOPMENT_ENVIRONMENT',true);

              # 設置數據庫連接所需數據

              define('DB_HOST','localhost');

              define('DB_NAME','todo');

              define('DB_USER','root');

              define('DB_PASSWORD','root');

              應該說config.php涉及到的內容并不多,不過是一些基礎數據的一些設置,再來看看library下的共用文件shared.php應該怎么寫。

              &lt;?php

              /* 檢查是否為開發環境并設置是否記錄錯誤日志 */

              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');

              }

              }

              /* 檢測敏感字符轉義(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);

              }

              }

              /* 檢測全局變量設置(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 =&gt; $var) {

              if ($var === $GLOBALS[$key]) {

              unset($GLOBALS[$key]);

              }

              }

              }

              }

              }

              /* 主請求方法,主要目的拆分URL請求 */

              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 {

              /* 生成錯誤代碼 */

              }

              }

              /* 自動加載控制器和模型 */

              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 {

              /* 生成錯誤代碼 */

              }

              }

              setReporting();

              removeMagicQuotes();

              unregisterGlobals();

              callHook();

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

              新建控制器基類為controller.class.php,控制器的主要功能就是總調度,具體具體內容如下:

              &lt;?php

              class Controller {

              protected $_model;

              protected $_controller;

              protected $_action;

              protected $_template;

              function __construct($model, $controller,$action) {

              $this-&gt;_controller = $controller;

              $this-&gt;_action = $action;

              $this-&gt;_model = $model;

              $this-&gt;$model =&amp; new $model;

              $this-&gt;_template =&amp; new Template($controller,$action);

              }

              function set($name,$value) {

              $this-&gt;_template-&gt;set($name,$value);

              }

              function __destruct() {

              $this-&gt;_template-&gt;render();

              }

              }

              新建控制器基類為model.class.php,考慮到模型需要對數據庫進行處理,所以可以新建一個數據庫基類sqlquery.class.php,模型去繼承sqlquery.class.php。

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

              &lt;?php

              class SQLQuery {

              protected $_dbHandle;

              protected $_result;

              /** 連接數據庫 **/

              function connect($address, $account, $pwd, $name) {

              $this-&gt;_dbHandle = @mysql_connect($address, $account, $pwd);

              if ($this-&gt;_dbHandle != 0) {

              if (mysql_select_db($name, $this-&gt;_dbHandle)) {

              return 1;

              }

              else {

              return 0;

              }

              }

              else {

              return 0;

              }

              }

              /** 中斷數據庫連接 **/

              function disconnect() {

              if (@mysql_close($this-&gt;_dbHandle) != 0) {

              return 1;

              }  else {

              return 0;

              }

              }

              /** 查詢所有數據表內容 **/

              function selectAll() {

              $query = 'select * from `'.$this-&gt;_table.'`';

              return $this-&gt;query($query);

              }

              /** 查詢數據表指定列內容 **/

              function select($id) {

              $query = 'select * from `'.$this-&gt;_table.'` where `id` = ''.mysql_real_escape_string($id).''';

              return $this-&gt;query($query, 1);

              }

              /** 自定義SQL查詢語句 **/

              function query($query, $singleResult = 0) {

              $this-&gt;_result = mysql_query($query, $this-&gt;_dbHandle);

              if (preg_match("/select/i",$query)) {

              $result = array();

              $table = array();

              $field = array();

              $tempResults = array();

              $numOfFields = mysql_num_fields($this-&gt;_result);

              for ($i = 0; $i &lt; $numOfFields; ++$i) {

              array_push($table,mysql_field_table($this-&gt;_result, $i));

              array_push($field,mysql_field_name($this-&gt;_result, $i));

              }

              while ($row = mysql_fetch_row($this-&gt;_result)) {

              for ($i = 0;$i &lt; $numOfFields; ++$i) {

              $table[$i] = trim(ucfirst($table[$i]),"s");

              $tempResults[$table[$i]][$field[$i]] = $row[$i];

              }

              if ($singleResult == 1) {

              mysql_free_result($this-&gt;_result);

              return $tempResults;

              }

              array_push($result,$tempResults);

              }

              mysql_free_result($this-&gt;_result);

              return($result);

              }

              }

              /** 返回結果集行數 **/

              function getNumRows() {

              return mysql_num_rows($this-&gt;_result);

              }

              /** 釋放結果集內存 **/

              function freeResult() {

              mysql_free_result($this-&gt;_result);

              }

              /** 返回MySQL操作錯誤信息 **/

              function getError() {

              return mysql_error($this-&gt;_dbHandle);

              }

              }

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

              &lt;?php

              class Model extends SQLQuery{

              protected $_model;

              function __construct() {

              $this-&gt;connect(DB_HOST,DB_USER,DB_PASSWORD,DB_NAME);

              $this-&gt;_model = get_class($this);

              $this-&gt;_table = strtolower($this-&gt;_model)."s";

              }

              function __destruct() {

              }

              }

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

              &lt;?php

              class Template {

              protected $variables = array();

              protected $_controller;

              protected $_action;

              function __construct($controller,$action) {

              $this-&gt;_controller = $controller;

              $this-&gt;_action =$action;

              }

              /* 設置變量 */

              function set($name,$value) {

              $this-&gt;variables[$name] = $value;

              }

              /* 顯示模板 */

              function render() {

              extract($this-&gt;variables);

              if (file_exists(ROOT.DS. 'application' .DS. 'views' .DS. $this-&gt;_controller .DS. 'header.php')) {

              include(ROOT.DS. 'application' .DS. 'views' .DS. $this-&gt;_controller .DS. 'header.php');

              } else {

              include(ROOT.DS. 'application' .DS. 'views' .DS. 'header.php');

              }

              include (ROOT.DS. 'application' .DS. 'views' .DS. $this-&gt;_controller .DS. $this-&gt;_action . '.php');

              if (file_exists(ROOT.DS. 'application' .DS. 'views' .DS. $this-&gt;_controller .DS. 'footer.php')) {

              include (ROOT.DS. 'application' .DS. 'views' .DS. $this-&gt;_controller .DS. 'footer.php');

              } else {

              include (ROOT.DS. 'application' .DS. 'views' .DS. 'footer.php');

              }

              }

              }

              做完了以上這么多操作,基本上整個MVC框架已經出來了,下面就該制作我們的站點了。我們要做的站點其實很簡單,一個ToDo程序。

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

              &lt;?php

              class ItemsController extends Controller {

              function view($id = null,$name = null) {

              $this-&gt;set('title',$name.' - My Todo List App');

              $this-&gt;set('todo',$this-&gt;Item-&gt;select($id));

              }

              function viewall() {

              $this-&gt;set('title','All Items - My Todo List App');

              $this-&gt;set('todo',$this-&gt;Item-&gt;selectAll());

              }

              function add() {

              $todo = $_POST['todo'];

              $this-&gt;set('title','Success - My Todo List App');

              $this-&gt;set('todo',$this-&gt;Item-&gt;query(' into items (item_name) values (''.mysql_real_escape_string($todo).'')'));

              }

              function ($id) {

              $this-&gt;set('title','Success - My Todo List App');

              $this-&gt;set('todo',$this-&gt;Item-&gt;query(' from items where id = ''.mysql_real_escape_string($id).'''));

              }

              }

              接下來就是先建站點的模型,在我們的/application/model/ 目錄下面先建一個站點模型類為Item,內容直接繼承Model,代碼如下:

              &lt;?php

              class Item extends Model {

              }

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

              view.php文件:查看單條待處理事務

              &lt;h2&gt;&lt;?php echo $todo['Item']['item_name']?&gt;&lt;/h2&gt;

              &lt;a href="../../../items//&lt;?php echo $todo['Item']['id']?&gt;"&gt;

              &lt;span&gt;Delete this item&lt;/span&gt;

              &lt;/a&gt;

              viewall.php文件:查看所有待處理事務

              &lt;form action="../items/add" method="post"&gt;

              &lt;input type="text" value="I have to..." onclick="this.value=''" name="todo"&gt; &lt;input type="submit" value="add"&gt;

              &lt;/form&gt;

              &lt;br/&gt;&lt;br/&gt;

              &lt;?php $number = 0?&gt;

              &lt;?php foreach ($todo as $todoitem):?&gt;

              &lt;a href="../items/view/&lt;?php echo $todoitem['Item']['id']?&gt;/&lt;?php echo strtolower(str_replace(" ","-",$todoitem['Item']['item_name']))?&gt;"&gt;

              &lt;span&gt;

              &lt;?php echo ++$number?&gt;

              &lt;?php echo $todoitem['Item']['item_name']?&gt;

              &lt;/span&gt;

              &lt;/a&gt;&lt;br/&gt;

              &lt;?php endforeach?&gt;

              add.php文件:添加待處理事務

              1

              &lt;a href="../items/viewall"&gt;Todo successfully added. Click here to go back.&lt;/a&gt;&lt;br/&gt;

              .php文件:刪除事務

              1

              &lt;a href="../../items/viewall"&gt;Todo successfully d. Click here to go back.&lt;/a&gt;&lt;br/&gt;

              header.php:頁首文件

              &lt;html&gt;

              &lt;head&gt;

              &lt;title&gt;&lt;?php echo $title?&gt;&lt;/title&gt;

              &lt;style&gt;

              .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;}

              &lt;/style&gt;

              &lt;/head&gt;

              &lt;body&gt;

              &lt;h1&gt;My Todo-List App&lt;/h1&gt;

              footer.php:頁尾文件

              1

              2

              &lt;/body&gt;

              &lt;/html&gt;

              當然還有一個必不可少的操作就是在數據中中建立一張表,具體代碼如下:

              CREATE TABLE IF NOT EXISTS `items` (

              `id` int(11) NOT NULL AUTO_INCREMENT,

              `item_name` var255) NOT NULL,

              PRIMARY KEY (`id`)

              ) ENGINE=MyISAM  DEFAULT CHARSET=latin1 AUTO_INCREMENT=17 ;

              至此一個使用MVC開發的網站就開發完成了。


            【如何使用PHP開發自己的MVC框架】相關文章:

            如何使用PHP框架09-12

            PHP MVC框架路由學習筆記07-02

            如何使用PHP開發高效的web系統10-19

            用Composer構建自己的PHP框架09-16

            php開發環境的搭建和使用10-01

            如何使用php中session08-27

            教你如何使用php的session07-13

            PHP.MVC的模板標簽系統09-19

            如何配置PHP開發環境07-21

            <delect id="sj01t"></delect>
            1. <em id="sj01t"><label id="sj01t"></label></em>
            2. <div id="sj01t"></div>
              1. <em id="sj01t"></em>

                      <div id="sj01t"></div>
                      黄色视频在线观看