[转]1小时内打造你自己的PHP MVC框架

简介

MVC框架在现在的开发中相当流行,不论你使用的是JAVA,C#,PHP或者IOS,你肯定都会选择一款框架。虽然不能保证100%的开发语言都会使用框架,但是在PHP社区当中拥有*多数量的MVC框架。今天你或许还在使用Zend,明天你换了另一个项目也许就会转投Yii,Laravel或者CakePHP的怀抱。如果你刚开始使用一种框架,当你看它的源码的时候你会觉得一头雾水,是的,这些框架都很复杂。因为这些流行的框架并不是短时间之内就写出来就发行的,它们都是经过一遍又一遍的编写和测试加上不断的更新函数库才有了今天得模样。所以就我的经验来看,了解MVC框架的设计核心理念是很有必要的,不然你就会感觉在每一次使用一个新的框架的时候一遍又一遍的从头学习。

 

所以*好的理解MVC的方法就是写一个你自己的MVC框架。在这篇文章中,我将会向你展示如何构建一个自己的MVC框架

MVC架构模式

M: Model-模型

V: View-视图

C: Controller-控制器

 

MVC的关键概念就是从视图层分发业务逻辑。首先解释以下HTTP的请求和相应是如何工作的。例如,我们有一个商城网站,然后我们想要添加一个商品,那么*简单的一个URL就会是像下面这个样子:

http://bestshop.com/index.php?p=admin&c=goods&a=add

 

http://bestshop.com就是主域名或者基础URL;

p=admin 意味着处在管理模块,,或者是系统的后台模块。同时我们肯定也拥有前台模块,前台模块供所有用户访问(本例中, 它是p=public)


c=goods&a=add 意思是URL请求的是goods控制器里的add方法。

前台控制器设计

在上面的例子中index.php中是什么?在PHP框架中它被称为入口文件。这个文件通常都被命名为index.php,当然你也可以给它别的命名。这个index.php的*主要的作用就是作为HTTP请求的唯一入口文件,这样无论你的URL请求什么资源,它都必须通过这个Index.php来请求。你可能要问为什么,它是如何做到的?PHP中的前端控制器用到了Apache服务器的分布式配置.htaccess实现的。在这个文件中,我们可以使用重写模块告诉Apache服务器重定向到我们的index.php入口文件,就像下面这样:

<IfModule mod_rewrite.c>

   

   Options +FollowSymLinks

   RewriteEngine on


   # Send request via index.php

   RewriteCond %{REQUEST_FILENAME} !-f

   RewriteCond %{REQUEST_FILENAME} !-d

   RewriteRule ^(.*)$ index.php/$1 [L]


</IfModule>

这个配置文件非常有用,还有当你重写这个配置文件的时候你不需要重启Apache。但是当你修改Apache的其他配置文件的时候你都需要重启Apache才能生效,因为Apache只有在启动的时候才会读取这些配置文件。

同时,index.php还会进行框架的初始化并且分发路由请求给对应的控制器和方法。

我们的MVC目录结构

现在让我们开始创建我们的框架目录结构。我们你可以随便先建立一个文件夹,命名为你项目的名称,比如:/bestshop。在这个文件夹下你需要建立下面的文件夹:

/application-存放web应用程序目录

/framework-存放框架文件目录

/public-存放所有的公共的静态资源,比如HTML文件,CSS文件和jJS文件。

index.php-唯一入口文件

 

然后在application文件夹下再建立下一级的目录

/config-存放应用的配置文件

/controllers-应用的控制器类

/model-应用的模型类

/view-应用的视图文件

 

现在在application/controllers文件夹下,我们还需要创建两个文件夹,一个frontend,一个backend:

同样的,在view下也建立frontend和backend文件夹:

 

就像你看到的,在application的controllers和view下面建立了backen和frontend文件夹,就像我们的用用有前台和后台功能一样。但是为什么不在model下也这样做呢?

Well, the reason here is, normally for a web app:是因为一般在我们的应用中,前台和后台其实是可以看做是两个“网站的”,但是CRUD操作的是同一个数据库,这就是问什么管理员更新了货物的价格的时候,前台用户可以马上看到价格的变化,因为前台和后台是共享一个数据库(表)的。所以在model中没必要再去建立两个文件夹。

  

:现在让我们回到framework文件夹中,一些框架的文件夹命名会用框架的名字命名,比如"symfony"。在framework中让我们快速建立下面的子目录:

/core-框架核心文件目录

/database-数据库目录(比如数据库启动类)

/helpers-辅助函数目录

/libraries-类库目录

现在进入public文件夹,建立下面的目录:

/css-存放css文件

/images-存放图片文件

/js-存放js文件

/uploads-存放上传的文件

OK。到目前为止这就是我们这个迷你的MVC框架的目录结构了!

框架核心类

现在在framework/core下建立一个Framework.class.php的文件。写入以下代码:

 1 // framework/core/Framework.class.php
 2 
 3 class Framework {
 4 
 5 
 6    public static function run() {
 7 
 8        echo "run()";
 9 
10    }

我们创建了一个静态方法run(),现在让我们通过入口文件index.php测试一下:

1 <?php
2 
3 
4 require "framework/core/Framework.class.php";
5 
6 
7 Framework::run();

你可以在你的浏览器里访问index.php看到结果。通常这个静态方法被命名为run()或者bootstrap()。在这个方法中,我们要做3件*主要的事情:

 1 class Framework {
 2 
 3 
 4    public static function run() {
 5 
 6 //        echo "run()";
 7 
 8        self::init();
 9 
10        self::autoload();
11 
12        self::dispatch();
13 
14    }
15 
16 
17    private static function init() {
18 
19    }
20 
21 
22    private static function autoload() {
23 
24 
25    }
26 
27 
28    private static function dispatch() {
29 
30 
31    }
32 
33 }

初始化

init()方法:

 1 // Initialization
 2 
 3 private static function init() {
 4 
 5     // Define path constants
 6 
 7     define("DS", DIRECTORY_SEPARATOR);
 8 
 9     define("ROOT", getcwd() . DS);
10 
11     define("APP_PATH", ROOT . 'application' . DS);
12 
13     define("FRAMEWORK_PATH", ROOT . "framework" . DS);
14 
15     define("PUBLIC_PATH", ROOT . "public" . DS);
16 
17 
18     define("CONFIG_PATH", APP_PATH . "config" . DS);
19 
20     define("CONTROLLER_PATH", APP_PATH . "controllers" . DS);
21 
22     define("MODEL_PATH", APP_PATH . "models" . DS);
23 
24     define("VIEW_PATH", APP_PATH . "views" . DS);
25 
26 
27     define("CORE_PATH", FRAMEWORK_PATH . "core" . DS);
28 
29     define('DB_PATH', FRAMEWORK_PATH . "database" . DS);
30 
31     define("LIB_PATH", FRAMEWORK_PATH . "libraries" . DS);
32 
33     define("HELPER_PATH", FRAMEWORK_PATH . "helpers" . DS);
34 
35     define("UPLOAD_PATH", PUBLIC_PATH . "uploads" . DS);
36 
37 
38     // Define platform, controller, action, for example:
39 
40     // index.php?p=admin&c=Goods&a=add
41 
42     define("PLATFORM", isset($_REQUEST['p']) ? $_REQUEST['p'] : 'home');
43 
44     define("CONTROLLER", isset($_REQUEST['c']) ? $_REQUEST['c'] : 'Index');
45 
46     define("ACTION", isset($_REQUEST['a']) ? $_REQUEST['a'] : 'index');
47 
48 
49     define("CURR_CONTROLLER_PATH", CONTROLLER_PATH . PLATFORM . DS);
50 
51     define("CURR_VIEW_PATH", VIEW_PATH . PLATFORM . DS);
52 
53 
54     // Load core classes
55 
56     require CORE_PATH . "Controller.class.php";
57 
58     require CORE_PATH . "Loader.class.php";
59 
60     require DB_PATH . "Mysql.class.php";
61 
62     require CORE_PATH . "Model.class.php";
63 
64 
65     // Load configuration file
66 
67     $GLOBALS['config'] = include CONFIG_PATH . "config.php";
68 
69 
70     // Start session
71 
72     session_start();
73 
74 }

在注释中你可以看到每一步的目的。

自动加载

在项目中,我们不想在脚本中想使用一个类的时候手动的去include或者require加载,这就是为什么PHP MVC框架都有自动加载的功能。例如,在symfony中,如果你想要加载lib下的类,它将会被自动引入。很神奇是吧?现在让我们在自己的框架中加入自动加载的功能。

 

这里我们要用的PHP中的自带函数spl_autoload_register:

 1 // Autoloading
 2 
 3 private static function autoload(){
 4 
 5     spl_autoload_register(array(__CLASS__,'load'));
 6 
 7 }
 8 
 9 
10 // Define a custom load method
11 
12 private static function load($classname){
13 
14 
15     // Here simply autoload app&rsquo;s controller and model classes
16 
17     if (substr($classname, -10) == "Controller"){
18 
19         // Controller
20 
21         require_once CURR_CONTROLLER_PATH . "$classname.class.php";
22 
23     } elseif (substr($classname, -5) == "Model"){
24 
25         // Model
26 
27         require_once  MODEL_PATH . "$classname.class.php";
28 
29     }
30 
31 }

每一个框架都有自己的命名规则,我们的也不例外。对于一个控制器类,它需要被命名成类似xxxController.class.php,对于一个模型类,需要被命名成xxModel.class.php。为什么在使用一个框架的时候你需要遵守它的命名规则呢?自动加载就是一条原因。

路由/分发

// Routing and dispatching

private static function dispatch(){

    // Instantiate the controller class and call its action method

    $controller_name = CONTROLLER . "Controller";

    $action_name = ACTION . "Action";

    $controller = new $controller_name;

    $controller->$action_name();

}
在这步中,index.php将会分发请求到对应的Controller::Aciton()方法中。
 
 
 

基础Controller类

通常在框架的核心类中都有一个基础的控制器。在symfony中,被称为sfAction;在iOS中,被称为UIViewController。在这里我们命名为Controller,在framework/core下建立Controller.class.php

 1 <?php
 2 
 3 // Base Controller
 4 
 5 class Controller{
 6 
 7     // Base Controller has a property called $loader, it is an instance of Loader class(introduced later)
 8 
 9     protected $loader;
10 
11 
12     public function __construct(){
13 
14         $this->loader = new Loader();
15 
16     }
17 
18 
19     public function redirect($url,$message,$wait = 0){
20 
21         if ($wait == 0){
22 
23             header("Location:$url");
24 
25         } else {
26 
27             include CURR_VIEW_PATH . "message.html";
28 
29         }
30 
31 
32         exit;
33 
34     }
35 
36 }
37 基础控制器有一个变量$loader,它是Loader类的实例化(后面介绍)。准确的说,$this->loader是一个变量指向了被实例化的Load类。在这里我不过多的讨论,但是这的确是一个非常关键的概念。我遇到过一些PHP开发者相信在这个语句之后:
38 
39 $this->loader = new Loader();
40 $this->load是一个对象。不,它只是一个引用。这是从Java中开始使用的,在Java之前,在C++和Objective C中被称为指针。引用是个封装的指针类型。比如,在iOS(O-C)中,我们创建了一个对象:
41 
42 UIButton *btn = [UIButton alloc] init];

加载类

在framework.class.php中,我们已经封装好了应用的控制器和模型的自动加载。但是如何自动加载在framework目录中的类呢?现在我们可以新建一个Loader类,它会加载framework目录中的类和函数。当我们加载framework类时,只需要调用这个Loader类中的方法即可。

 1 class Loader{
 2 
 3     // Load library classes
 4 
 5     public function library($lib){
 6 
 7         include LIB_PATH . "$lib.class.php";
 8 
 9     }
10 
11 
12     // loader helper functions. Naming conversion is xxx_helper.php;
13 
14     public function helper($helper){
15 
16         include HELPER_PATH . "{$helper}_helper.php";
17 
18     }
19 
20 }

封装模型

我们需要下面两个类来封装基础Model类:

Mysql.class.php - 在framework/database下建立,它封装了数据库的链接和一些基本查询方法。

 

Model.class.php - framework/core下建立,基础模型类,封装所有的CRUD方法。

 

Mysql.class.php :

  1 <?php
  2 
  3 /**
  4 
  5 *================================================================
  6 
  7 *framework/database/Mysql.class.php
  8 
  9 *Database operation class
 10 
 11 *================================================================
 12 
 13 */
 14 
 15 class Mysql{
 16 
 17     protected $conn = false;  //DB connection resources
 18 
 19     protected $sql;           //sql statement
 20 
 21    
 22 
 23     /**
 24 
 25      * Constructor, to connect to database, select database and set charset
 26 
 27      * @param $config string configuration array
 28 
 29      */
 30 
 31     public function __construct($config = array()){
 32 
 33         $host = isset($config['host'])? $config['host'] : 'localhost';
 34 
 35         $user = isset($config['user'])? $config['user'] : 'root';
 36 
 37         $password = isset($config['password'])? $config['password'] : '';
 38 
 39         $dbname = isset($config['dbname'])? $config['dbname'] : '';
 40 
 41         $port = isset($config['port'])? $config['port'] : '3306';
 42 
 43         $charset = isset($config['charset'])? $config['charset'] : '3306';
 44 
 45        
 46 
 47         $this->conn = mysql_connect("$host:$port",$user,$password) or die('Database connection error');
 48 
 49         mysql_select_db($dbname) or die('Database selection error');
 50 
 51         $this->setChar($charset);
 52 
 53     }
 54 
 55     /**
 56 
 57      * Set charset
 58 
 59      * @access private
 60 
 61      * @param $charset string charset
 62 
 63      */
 64 
 65     private function setChar($charest){
 66 
 67         $sql = 'set names '.$charest;
 68 
 69         $this->query($sql);
 70 
 71     }
 72 
 73     /**
 74 
 75      * Execute SQL statement
 76 
 77      * @access public
 78 
 79      * @param $sql string SQL query statement
 80 
 81      * @return $result,if succeed, return resrouces; if fail return error message and exit
 82 
 83      */
 84 
 85     public function query($sql){        
 86 
 87         $this->sql = $sql;
 88 
 89         // Write SQL statement into log
 90 
 91         $str = $sql . "  [". date("Y-m-d H:i:s") ."]" . PHP_EOL;
 92 
 93         file_put_contents("log.txt", $str,FILE_APPEND);
 94 
 95         $result = mysql_query($this->sql,$this->conn);
 96 
 97        
 98 
 99         if (! $result) {
100 
101             die($this->errno().':'.$this->error().'<br />Error SQL statement is '.$this->sql.'<br />');
102 
103         }
104 
105         return $result;
106 
107     }
108 
109     /**
110 
111      * Get the first column of the first record
112 
113      * @access public
114 
115      * @param $sql string SQL query statement
116 
117      * @return return the value of this column
118 
119      */
120 
121     public function getOne($sql){
122 
123         $result = $this->query($sql);
124 
125         $row = mysql_fetch_row($result);
126 
127         if ($row) {
128 
129             return $row[0];
130 
131         } else {
132 
133             return false;
134 
135         }
136 
137     }
138 
139     /**
140 
141      * Get one record
142 
143      * @access public
144 
145      * @param $sql SQL query statement
146 
147      * @return array associative array
148 
149      */
150 
151     public function getRow($sql){
152 
153         if ($result = $this->query($sql)) {
154 
155             $row = mysql_fetch_assoc($result);
156 
157             return $row;
158 
159         } else {
160 
161             return false;
162 
163         }
164 
165     }
166 
167     /**
168 
169      * Get all records
170 
171      * @access public
172 
173      * @param $sql SQL query statement
174 
175      * @return $list an 2D array containing all result records
176 
177      */
178 
179     public function getAll($sql){
180 
181         $result = $this->query($sql);
182 
183         $list = array();
184 
185         while ($row = mysql_fetch_assoc($result)){
186 
187             $list[] = $row;
188 
189         }
190 
191         return $list;
192 
193     }
194 
195     /**
196 
197      * Get the value of a column
198 
199      * @access public
200 
201      * @param $sql string SQL query statement
202 
203      * @return $list array an array of the value of this column
204 
205      */
206 
207     public function getCol($sql){
208 
209         $result = $this->query($sql);
210 
211         $list = array();
212 
213         while ($row = mysql_fetch_row($result)) {
214 
215             $list[] = $row[0];
216 
217         }
218 
219         return $list;
220 
221     }
222 
223 
224    
225 
226     /**
227 
228      * Get last insert id
229 
230      */
231 
232     public function getInsertId(){
233 
234         return mysql_insert_id($this->conn);
235 
236     }
237 
238     /**
239 
240      * Get error number
241 
242      * @access private
243 
244      * @return error number
245 
246      */
247 
248     public function errno(){
249 
250         return mysql_errno($this->conn);
251 
252     }
253 
254     /**
255 
256      * Get error message
257 
258      * @access private
259 
260      * @return error message
261 
262      */
263 
264     public function error(){
265 
266         return mysql_error($this->conn);
267 
268     }
269 
270 }
271  

Model.class.php:

  1 <?php
  2 
  3 // framework/core/Model.class.php
  4 
  5 // Base Model Class
  6 
  7 class Model{
  8 
  9     protected $db; //database connection object
 10 
 11     protected $table; //table name
 12 
 13     protected $fields = array();  //fields list
 14 
 15     public function __construct($table){
 16 
 17         $dbconfig['host'] = $GLOBALS['config']['host'];
 18 
 19         $dbconfig['user'] = $GLOBALS['config']['user'];
 20 
 21         $dbconfig['password'] = $GLOBALS['config']['password'];
 22 
 23         $dbconfig['dbname'] = $GLOBALS['config']['dbname'];
 24 
 25         $dbconfig['port'] = $GLOBALS['config']['port'];
 26 
 27         $dbconfig['charset'] = $GLOBALS['config']['charset'];
 28 
 29        
 30 
 31         $this->db = new Mysql($dbconfig);
 32 
 33         $this->table = $GLOBALS['config']['prefix'] . $table;
 34 
 35         $this->getFields();
 36 
 37     }
 38 
 39     /**
 40 
 41      * Get the list of table fields
 42 
 43      *
 44 
 45      */
 46 
 47     private function getFields(){
 48 
 49         $sql = "DESC ". $this->table;
 50 
 51         $result = $this->db->getAll($sql);
 52 
 53         foreach ($result as $v) {
 54 
 55             $this->fields[] = $v['Field'];
 56 
 57             if ($v['Key'] == 'PRI') {
 58 
 59                 // If there is PK, save it in $pk
 60 
 61                 $pk = $v['Field'];
 62 
 63             }
 64 
 65         }
 66 
 67         // If there is PK, add it into fields list
 68 
 69         if (isset($pk)) {
 70 
 71             $this->fields['pk'] = $pk;
 72 
 73         }
 74 
 75     }
 76 
 77     /**
 78 
 79      * Insert records
 80 
 81      * @access public
 82 
 83      * @param $list array associative array
 84 
 85      * @return mixed If succeed return inserted record id, else return false
 86 
 87      */
 88 
 89     public function insert($list){
 90 
 91         $field_list = '';  //field list string
 92 
 93         $value_list = '';  //value list string
 94 
 95         foreach ($list as $k => $v) {
 96 
 97             if (in_array($k, $this->fields)) {
 98 
 99                 $field_list .= "`".$k."`" . ',';
100 
101                 $value_list .= "'".$v."'" . ',';
102 
103             }
104 
105         }
106 
107         // Trim the comma on the right
108 
109         $field_list = rtrim($field_list,',');
110 
111         $value_list = rtrim($value_list,',');
112 
113         // Construct sql statement
114 
115         $sql = "INSERT INTO `{$this->table}` ({$field_list}) VALUES ($value_list)";
116 
117         if ($this->db->query($sql)) {
118 
119             // Insert succeed, return the last record&rsquo;s id
120 
121             return $this->db->getInsertId();
122 
123             //return true;
124 
125         } else {
126 
127             // Insert fail, return false
128 
129             return false;
130 
131         }
132 
133        
134 
135     }
136 
137     /**
138 
139      * Update records
140 
141      * @access public
142 
143      * @param $list array associative array needs to be updated
144 
145      * @return mixed If succeed return the count of affected rows, else return false
146 
147      */
148 
149     public function update($list){
150 
151         $uplist = ''; //update fields
152 
153         $where = 0;   //update condition, default is 0
154 
155         foreach ($list as $k => $v) {
156 
157             if (in_array($k, $this->fields)) {
158 
159                 if ($k == $this->fields['pk']) {
160 
161                     // If it&rsquo;s PK, construct where condition
162 
163                     $where = "`$k`=$v";
164 
165                 } else {
166 
167                     // If not PK, construct update list
168 
169                     $uplist .= "`$k`='$v'".",";
170 
171                 }
172 
173             }
174 
175         }
176 
177         // Trim comma on the right of update list
178 
179         $uplist = rtrim($uplist,',');
180 
181         // Construct SQL statement
182 
183         $sql = "UPDATE `{$this->table}` SET {$uplist} WHERE {$where}";
184 
185        
186 
187         if ($this->db->query($sql)) {
188 
189             // If succeed, return the count of affected rows
190 
191             if ($rows = mysql_affected_rows()) {
192 
193                 // Has count of affected rows  
194 
195                 return $rows;
196 
197             } else {
198 
199                 // No count of affected rows, hence no update operation
200 
201                 return false;
202 
203             }    
204 
205         } else {
206 
207             // If fail, return false
208 
209             return false;
210 
211         }
212 
213        
214 
215     }
216 
217     /**
218 
219      * Delete records
220 
221      * @access public
222 
223      * @param $pk mixed could be an int or an array
224 
225      * @return mixed If succeed, return the count of deleted records, if fail, return false
226 
227      */
228 
229     public function delete($pk){
230 
231         $where = 0; //condition string
232 
233         //Check if $pk is a single value or array, and construct where condition accordingly
234 
235         if (is_array($pk)) {
236 
237             // array
238 
239             $where = "`{$this->fields['pk']}` in (".implode(',', $pk).")";
240 
241         } else {
242 
243             // single value
244 
245             $where = "`{$this->fields['pk']}`=$pk";
246 
247         }
248 
249         // Construct SQL statement
250 
251         $sql = "DELETE FROM `{$this->table}` WHERE $where";
252 
253         if ($this->db->query($sql)) {
254 
255             // If succeed, return the count of affected rows
256 
257             if ($rows = mysql_affected_rows()) {
258 
259                 // Has count of affected rows
260 
261                 return $rows;
262 
263             } else {
264 
265                 // No count of affected rows, hence no delete operation
266 
267                 return false;
268 
269             }        
270 
271         } else {
272 
273             // If fail, return false
274 
275             return false;
276 
277         }
278 
279     }
280 
281     /**
282 
283      * Get info based on PK
284 
285      * @param $pk int Primary Key
286 
287      * @return array an array of single record
288 
289      */
290 
291     public function selectByPk($pk){
292 
293         $sql = "select * from `{$this->table}` where `{$this->fields['pk']}`=$pk";
294 
295         return $this->db->getRow($sql);
296 
297     }
298 
299     /**
300 
301      * Get the count of all records
302 
303      *
304 
305      */
306 
307     public function total(){
308 
309         $sql = "select count(*) from {$this->table}";
310 
311         return $this->db->getOne($sql);
312 
313     }
314 
315     /**
316 
317      * Get info of pagination
318 
319      * @param $offset int offset value
320 
321      * @param $limit int number of records of each fetch
322 
323      * @param $where string where condition,default is empty
324 
325      */
326 
327     public function pageRows($offset, $limit,$where = ''){
328 
329         if (empty($where)){
330 
331             $sql = "select * from {$this->table} limit $offset, $limit";
332 
333         } else {
334 
335             $sql = "select * from {$this->table}  where $where limit $offset, $limit";
336 
337         }
338 
339        
340 
341         return $this->db->getAll($sql);
342 
343     }
344 
345 }
346  

现在我们可以在application下创建一个User模型,对应数据库里的user表:

 1 <?php
 2 
 3 // application/models/UserModel.class.php
 4 
 5 class UserModel extends Model{
 6 
 7 
 8     public function getUsers(){
 9 
10         $sql = "select * from $this->table";
11 
12         $users = $this->db->getAll($sql);
13 
14         return $users;
15 
16     }
17 
18 }

后台的indexController:

 1 <?php
 2 
 3 // application/controllers/admin/IndexController.class.php
 4 
 5 
 6 class IndexController extends BaseController{
 7 
 8     public function mainAction(){
 9 
10         include CURR_VIEW_PATH . "main.html";
11 
12         // Load Captcha class
13 
14         $this->loader->library("Captcha");
15 
16         $captcha = new Captcha;
17 
18         $captcha->hello();
19 
20         $userModel = new UserModel("user");
21 
22         $users = $userModel->getUsers();
23 
24     }
25 
26     public function indexAction(){
27 
28                        $userModel = new UserModel("user");
29 
30         $users = $userModel->getUsers();
31 
32         // Load View template
33 
34         include  CURR_VIEW_PATH . "index.html";
35 
36     }
37 
38     public function menuAction(){
39 
40         include CURR_VIEW_PATH . "menu.html";
41 
42     }
43 
44     public function dragAction(){
45 
46         include CURR_VIEW_PATH . "drag.html";
47 
48     }
49 
50     public function topAction(){
51 
52         include CURR_VIEW_PATH . "top.html";
53 
54     }
55 
56 }

到目前为止,我们后台的index控制器就正常执行了,控制器中实例化了模型类,并且将得到的数据传给了视图中的模板,这样在浏览器中就能看到数据了。

 

转自:phpchina原创译文  1小时内打造你自己的PHP MVC框架  http://www.phpchina.com/article-40109-1.html

原文链接:http://www.codeproject.com/Articles/1080626/WebControls/

原文地址:https://www.cnblogs.com/EdwinChan/p/7484597.html