前言
通过学习MVC能够更深的了解一些mvc框架
MVC 思想
MVC是一个设计模式,它强制性的使应用程序的输入、处理和输出分开。使用MVC应用程序被分成三个核心部件:模型(M)、视图(V)、控制器(C),它们各自处理自己的任务。
视图:视图是用户看到并与之交互的界面。对老式的Web应用程序来说,视图就是由HTML元素组成的界面,在新式的Web应用程序中,HTML依旧在视图中扮演着重要的角色,但一些新的技术已层出不穷,它们包括Adobe Flash和象XHTML,XML/XSL,WML等一些标识语言和Web services。如何处理应用程序的界面变得越来越有挑战性。MVC一个大的好处是它能为你的应用程序处理很多不同的视图。在视图中其实没有真正的处理发生,不管这些数据是联机存储的还是一个雇员列表,作为视图来讲,它只是作为一种输出数据并允许用户操纵的方式。
模型:模型表示企业数据和业务规则。在MVC的三个部件中,模型拥有最多的处理任务。例如它可能用象EJBs和ColdFusion Components这样的构件对象来处理数据库。被模型返回的数据是中立的,就是说模型与数据格式无关,这样一个模型能为多个视图提供数据。由于应用于模型的代码只需写一次就可以被多个视图重用,所以减少了代码的重复性。
控制器:控制器接受用户的输入并调用模型和视图去完成用户的需求。所以当单击Web页面中的超链接和发送HTML表单时,控制器本身不输出任何东西和做任何处理。它只是接收请求并决定调用哪个模型构件去处理请求,然后确定用哪个视图来显示模型处理返回的数据。
单一入口
单一入口通常是指一个项目或者应用具有一个统一(但并不一定是唯一)的入口文件,也就是说项目的所有功能操作都是通过这个入口文件进行的,并且往往入口文件是第一步被执行的。
单一入口的好处是项目整体比较规范,因为同一个入口,往往其不同操作之间具有相同的规则。另外一个方面就是单一入口带来的好处是控制较为灵活,因为拦截方便了,类似如一些权限控制、用户登录方面的判断和操作可以统一处理了。
或者有些人会担心所有网站都通过一个入口文件进行访问,是否会造成太大的压力,其实这是杞人忧天的想法。
现在我们总结MVC的处理过程,首先控制器接收用户的请求,并决定应该调用哪个模型来进行处理,然后模型用业务逻辑来处理用户的请求并返回数据,最后控制器用相应的视图格式化模型返回的数据,并通过表示层呈现给用户。
一个典型的Web MVC流程:
Controller截获用户发出的请求;
Controller调用Model完成状态的读写操作;
Controller把数据传递给View;
View渲染最终结果并呈献给用户。
代码规范
MySQL的表名需小写或小写加下划线,如:item,car_orders。
模块名(Models)需用大驼峰命名法,即首字母大写,并在名称后添加Model,如:ItemModel,CarModel。
控制器(Controllers)需用大驼峰命名法,即首字母大写,并在名称后添加Controller,如:ItemController,CarController。
方法名(Action)需用小驼峰命名法,即首字母小写,如:index,indexPost。
视图(Views)部署结构为控制器名/行为名,如:item/view.php,car/buy.php。
对于只有 PHP 代码的文件,最好没有结束标志?>,
PHP自身并不需要结束符号,不加结束符让程序更加安全,很大程度防止了末尾被注入额外的内容。
请求URL
ocalhost/index.php?c=demo&a=index¶m=welcome
如果想得到更加优美的URL结构,可以进行优化,为由这URL结构优化与本文关系不大,以后进行分享。
从上面的参数可以看出,访问的文件是index.php,同时含有3个参数分别为c、a、param。
MVC实现
首先来实现一个简单的MVC1
2
3
4
5
6
7
8├─www
│ ├─controller
│ │ ├─democontroller.php
│ ├─model
│ │ ├─model.php
│ ├─view
│ │ ├─index.php
│ ├─index.php
/index.php1
2
3
4
require('controller/democontroller.php');
$controller = new DemoController();
$controller->index();
controller/democontroller.php1
2
3
4
5
6
7
class DemoController{
public function index(){
echo "hello world";
}
}
访问127.0.0.1/index.php
如果使用下面的URL进行访问,可以预见不会有任何输出。
访问http://localhost/controller/democontroller.php
只能通过index.php来访问,这也是为什么称它为入口文件的原因
现在来通过参数来调用不同的控制器
接下来改写index.php内容1
2
3
4
5
6
7
8
9
10
11
$c_str = $_GET['c']; // 获取控制器
$c_name = $c_str.'controller';
$c_path = 'controller/'.$c_name.'.php';
$method = $_GET['a']; //方法名
require($c_path);
$controller = new $c_name;
$controller->$method();
访问
http://localhost/index.php?c=demo&a=index
同样能够得到内容
接下来加入view,使用视图对象处理输出
view/index.php1
2
3
4
5
6
7
8
9
class Index {
public function display($output) {
echo $output;
}
}
1 |
|
访问 http://localhost/index.php?c=demo&a=index
上面貌似已经很cool了,但是显示什么样的内容是在控制器中直接指定的,希望内容也由URL指定,这样将数据的处理交给模型来处理。
model/model.php1
2
3
4
5
6
7
8
9
10
11
12
// model/model.php
class Model{
private $data = array(
'title' => 'Hello style',
'key' => 'welcome to style-404.github.io',
);
public function getData($key){
return $this ->data[$key];
}
}
视图文件model.php定义了一个Model类,类中定义了一个getData()的方法,用于返回请求的数据。
同时修改入口文件index.php如下:
1 |
|
增加了一个参数$param,将其作为控制器的方法调用参数。
还需要修改控制器的方法根据不同参数取得不同的数据。
// controller/democontroller.php1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// controller/democontroller.php
class DemoController
{
function index($param)
{
// echo 'hello world';
require('view/index.php');
require('model/model.php');
$model = new Model();
$view = new Index();
$data = $model->getData($this->$param);
$view->display($data);
}
}
访问
http://localhost/index.php?c=demo&a=index¶m=key
成功~