一、什么是MVC
MVC,Model-View-Controller的简写,是软件工程中是一种软件的架构模式。它是一种编程思想,是一种设计模式。这种模式可以使网站的目录结构更加清晰,网站更易维护与扩展。
二、MVC的作用和目的
MVC的主要作用是为了将代码分层、分类。主要目的是为了解决Web开发中分离开发与设计工作,使其工作相对独立,便于后续对程序的修改和扩展简化,并且可以实现模块的复用。
三、MVC各部分的职能
Model(模型M):管理大部分的业务逻辑和所有的数据库逻辑。模型提供了连接和操作数据库的抽象层。在PHP中负责数据管理,数据生成。
View(视图V):图形界面逻辑。在PHP中负责输出,处理如何调用模板、需要的资源文件。通俗的说,就是负责渲染数据,通过HTML方式呈现给用户。
Controller(控制器C):负责响应用户请求、准备数据,以及决定如何展示数据。
四、MVC的实现
建立Model模型
代码演示:
namespacemvc_demo;
classModel
{
publicfunctiongetData()
{
return(new\PDO('mysql:host=localhost;dbname=phpedu','root','root'))
->query('SELECT * FROM `staffs` LIMIT 10')
->fetchAll(\PDO::FETCH_ASSOC);
}
}
// print_r((new Model)->getData());//打印测试数据
建立View视图
代码演示:
namespacemvc_demo;
classView
{
publicfunctionfetch($data)
{
$table='
$table.='
员工信息表';$table.='
ID姓名性别职务手机号入职时间';// 将数据循环遍历出来
foreach($dataas$staff){
$table.='
';$table.='
'.$staff['id'].'';$table.='
'.$staff['name'].'';$table.='
'.($staff['sex']?'男':'女').'';$table.='
'.$staff['position'].'';$table.='
'.$staff['mobile'].'';$table.='
'.date('Y年m月d日',$staff['hiredate']).'';$table.='
';}
$table.='
';return$table;
}
}
echo'
table {border-collapse: collapse; border: 1px solid;text-align: center; width: 500px;height: 150px;width: 600px;}
caption {font-size: 1.2rem; margin-bottom: 10px;}
tr:first-of-type { background-color:wheat;}
td,th {border: 1px solid; padding:5px}
';
// require 'Model.php';
// echo (new View)->fetch((new Model)->getData());//打印测试数据
建立Controller控制器
代码演示:
namespacemvc_demo;
// 1. 加载模型类
require'Model.php';
// 2. 加载视图
require'View.php';
// 3. 创建控制
classController1
{
publicfunctionindex()
{
// 1. 获取数据
$model=newModel;
$data=$model->getData();
// 2. 渲染模板/视图
$view=newView;
return$view->fetch($data);
}
}
// 客户端
// 实例化控制器类
$controller=newController1;
echo $controller->index();
输出效果:
五、MVC中的控制器对外部对象的两种依赖注入方式
上例中,虽然我们实现了控制器对模型和视图的关联,但是这种关联方式使得控制器对模型和视图两个类的过分依赖。而为了避免控制器过度依赖外部对象的问题,MVC中的控制器对外部对象提供了两种依赖注入方式:方法的依赖注入和构造函数的依赖注入。
1. 方法依赖注入
代码演示:
namespacemvc_demo;
// 控制器1
// 1. 加载模型类
require'Model.php';
// 2. 加载视图
require'View.php';
// 3. 创建控制
classController2
{
publicfunctionindex(Model$model,View$view)//通过参数的方式注入到index方法中
{
// 1. 获取数据
$data=$model->getData();
// 2. 渲染模板/视图
return$view->fetch($data);
}
publicfunctionindex2(Model$model,View$view)
{
}
}
// 客户端//
$model=newModel;
$view=newView;
// 实例化控制器类
$controller=newController2;
echo $controller->index($model,$view);
2. 构造函数的依赖注入
代码演示:
namespacemvc_demo;
// 1. 加载模型类
require'Model.php';
// 2. 加载视图
require'View.php';
// 3. 创建控制
classController3
{
// 依赖对象属性
private$model;
private$view;
//构造方法
publicfunction__construct(Model$model,View$view)
{
$this->model=$model;
$this->view=$view;
}
publicfunctionindex()
{
// 1. 获取数据
$data=$this->model->getData();
// 2. 渲染模板/视图
return$this->view->fetch($data);
}
publicfunctionindex2()
{
// 1. 获取数据
$data=$this->model->getData();
// 2. 渲染模板/视图
return$this->view->fetch($data);
}
}
// 客户端
$model=newModel;
$view=newView;
// 实例化控制器类
$controller=newController3($model,$view);
echo $controller->index($model,$view);
输出效果:
六、MVC与服务容器
虽然上面两种注入方式都可以解除控制器的耦合度问题,但是随着项目的扩大,代码量的增加,其缺点也会突显出来:一是需要修改大量代码,二是对程序员的知识储备要求很高,他需要看很多其他类文档,一个个的创建类,才有可能创建出程序员需要的变量。那么有没有一种方法,既可以简化代码,又可以在整个程序运行期间,随时可以调用,且程序员不用知道这个类太多的细节,甚至可以用一个字符串的别名来创建这样一个对象。答案是有的,它就是container服务容器,我们可以把容器简单的看成一个全局变量,并用关联数组把字符串和构造函数做绑定,轻松解决控制器的耦合度的相关问题。
代码演示:
namespacemvc_demo;
require'Model.php';
require'View.php';
// 创建服务容器
classContainer1
{
// 创建对象容器
protected$instances=[];
// 绑定: 向对象容器中添加一个类实例(类实例的别名alias)
publicfunctionbind($alias,\Closure $process)
{
$this->instances[$alias]=$process;
}
// 取出: 从容器中取出一个类实例 (new)
publicfunctionmake($alias,$params=[])
{
returncall_user_func_array($this->instances[$alias],[]);
}
}
$container=newContainer1;
// 绑定
$container->bind('model',function(){returnnewModel;});
$container->bind('view',function(){returnnewView;});
//创建控制器
classController4
{
publicfunctionindex(Container1$container)
{
// 1. 获取数据
$data=$container->make('model')->getData();
// 2. 渲染模板/视图
return$container->make('view')->fetch($data);
}
}
// 客户端
// 实例化控制器类
$controller=newController4();
echo $controller->index($container);
//追加销毁
unset($controller);
echo'销毁了';
echo'
';
总结:
1.MVC模式通过对复杂程序的简化,使程序结构更加直观。但是,对于像个人博客等轻量级的网站,使用MVC则会将简单的问题复杂化。所以在实际工作中,是否需要使用MVC模式,需要根据情况而定。
2.通过MVC模式自制框架,每个人都可以完全控制自己的框架,将自己的想法融入到自制的框架中。自己掌握主动权当然是好的。
3.解决问题的方法是没有绝对好的工具,只有相对优秀的解决方案,我们不能说服务容器是完美无缺的,每一种工具都有它的优缺点,而我们所要做的便是在实际使用中扬长避短。