一、MVC概述
1 混编方式
最早的php页面开发是将php代码和html代码放到一个脚本文件中,这种方式称为混编方式。
但是难以管理维护,已经淘汰了。
2 显示和逻辑分离
后来,将展示的html文件与业务处理的php文件分开。浏览器请求php逻辑文件,html对用户隐藏,在php文件中加载html文件。
~~模板文件:
html中可变的动态数据由php填充,但是php代码只负责输出数据,不负责处理数据。这样的文件叫做模板文件。使用的最多的就是echo,foreach、while。
~~模板文件隐藏:
用户不应该请求负责展示的模板文件,需要我们对模板文件隐藏起来。
可在apache、nginx中配置。.htaccess文件。
3 MVC思想架构
对于一个业务复杂的大型网站,显示和逻辑分离也不能更好的维护代码。于是在这基础上,再把逻辑中的所有的数据处理模块单独的提取出来,在需要功能上进行功能调度。这种思想就是MVC思想。
Model模型=》数据处理; Controller控制器=》功能调度;Vie视图 =》显示
M:Model,模型,项目中的数据处理单元,专门负责和数据库进行交互(增删改查)
V:View,视图,项目中用于结果展示的单元(以前的模板文件)
C:Controller,控制器,项目中负责某个功能整体流程调用的单元
浏览器只需要和C控制器进行交互,而模型M和视图V都被控制器所调用,并且模型M和V之间不存在任何的交互。浏览器只需请求stu_c文件即可。
~~优缺点:
代码结构分工明确,可读性强;代码结构分工明确,可读性强;代码结构分工明确,可读性强。
但是降低了代码运行的效率。
~~MVC与面向对象
mvc是架构思想,指项目中代码的组织关系,面向过程和面向对象都可以使用MVC的架构思想。但是mvc和面向对象才是黄金搭档。所以项目中的功能都要封装到类中。
二、MVC与面向对象
1.从模型类到控制器
A 模型类
把MVC中的数据处理单元的功能,封装到一个类中。一般项目开发中,一张数据表就对应着的一个模型类。模型类中定义的方法都是表的增删改查,如获取列表,删除,添加等功能。
~~举个例子
模型类中封装了学生表的列表信息和删除功能。在控制器内实例化对象调用即可。
B 引入基础模型类
封装的模型类中每个方法,都要传入参数,实例化数据库对象,同一个类的不同方法有大量重复的代码,而且其他类的方法也有可能出现该重复的代码。
为此我们引入基础模型类,在里面定义一些公共代码,被其他模型类继承。如在基础模型类中增加初始化数据库操作对象的功能。
~~模型类的单例模式
在一个控制器中(此时还未抽象化控制器类),对一个表需要进行多次操作,应该使用该表的一个模型就可以完成全部的任务。实例化模型类只需实例化一个即可。对每个模型类的实例化,我们用一个单例工厂类来完成类的实例化。模型类的单例定义静态数组存储。
2.从控制器类到入口文件
A 控制器类
实际开发中,将一系列相关或相似的功能,使用一个控制器来处理,而该控制器内的每一个方法,就对应着某一个具体的功能。
比如:增加学生,删除学生,修改学生的成绩等,可以用一个学生控制器类来完成。
控制器按功能划分,模型类按数据表划分。
~~举个例子
B 增加入口文件index.php
对控制器抽象为类后,请求需要实例化类并调用其中的action方法。在删除原来非控制器类的控制器文件后,增加一个入口文件,每一次的请求都通过入口文件实例化控制器类调用其中的方法。
index.php从mvc的角度就叫作前端控制器,也叫作入口文件。
C 动作分发a
一个控制器内对应多个功能,如何保证每一次不同的请求,只需经过一个入口文件?
在入口文件中增加动作分发功能,根据每一次请求传递的参数动作,规定要走控制器的哪个方法。
动作分发参数定义为a。
~~举个例子
index.php?a=list 代表当前请求的是学生列表的功能
index.php?a=remove 代表当前请求的是学生删除的功能
~~代码实现
第一次访问时不会携带a参数,需要给定默认值。在网页上点击时,需要在html中确定动作分发参数a的执行动作。
从功能的角度看,index.php也叫作请求分发器
D 控制器分发c
项目中有很多不同的控制器,完成不同的功能。比如,我们还可以再增加一个教师相关的操作控制器类。
这时就需要在一个入口文件中对不同的控制器完成分发。就需要使用到控制器Controller的分发参数c。
~~举个例子
在请求前端控制器index.php的时候,向其传递c参数,表示当前所需要执行的控制类的类名。
index.php?c=Stu&a=list 学生列表动作
index.php?c=Tea&a=list 教师列表动作
~~代码实现
同a参数一样,在入口文件中也需要定义一个默认的c参数,而也需要在其他的HTML链接地址中也主动增加c参数。
~~使用常量存储分发参数
在一次请求周期中,已经确定了请求的控制器和当前动作。上述代码用变量存储了控制器的名字和方法名。如果在代码中某些地方操作变量,会改变控制器名和代码名。所以用常量存储更为保险。
F 基础控制器类
控制器类中的不同方法都存在相同的代码,如前面的StuController控制器类中的两个动作以及TeaController中的list动作都使用到了header函数。
引入基础控制器类,把所有控制器的公共代码放到该类里面,其他控制器类继承该类。
~~代码实现
初始化文件编码方法,在实例化控制器类的时候由系统自动的进行初始化,放在构造方法中。
一个index.php文件完成了对不同控制器的不同方法分发,所以,index.php也叫作单入口文件,这种模式也叫作单入口模式。
3.目录布局
A 目录文件的规划
上述代码文件,有的是业务需求代码,有的是框架代码。创建相关目录把合适的文件放到合适的目录里,体现代码之间的组织关系。
框架代码Frame 在各个应用程序之间可以通用的代码
应用程序代码 App 针对当前项目的业务逻辑实现的代码,不同的项目各不相同。
入口文件放在网站根目录。
B 划分平台
一个项目中往往有多个端,如用于前端展示的前台,后端管理数据的后台,小程序端,app端等。
在App目录下添加前台后台两个子目录
~~ 平台内的mvc划分
各个平台之间应该是相对独立的,而各个平台的功能又是是由MVC来完成的。
~~整体目录布局
~~整体运行
文件目录的改变,相应的需要改变代码中类文件的引入路径。
目前是单入口程序,所有的相对地址,都是相当于入口文件index.php而言的.
C 平台分发p
index.php?p=Test&c=Stu&a=list
index.php?p=Home&c=User&a=register
~~代码实现
5.从入口文件到框架初始类
A 自动加载
代码中对类的实例化需要手动引入类文件,在入口文件中实现定义好自动加载函数,因为类的自动加载需要在实例化之前定义。
~~思路分析
所有需要加载的类文件有框架核心类(已经确定好了)、控制器类、模型类(可以增加)3种。
对于不确定的可以增加的类,需要通过类名的规律,完成其位置的判断,然后再进行自动的加载。
完成上述代码的实现,即可删除实例化中类文件的引入代码。
B 目录常量
代码中有很多地方用到了对目录的引入,如果改变文件位置,就需要对每一处的目录进行更改,为此将这些目录定义成目录常量,在入口文件处就可以完成统一修改。
~~定义基础目录常量
~~定义当前平台下的相关目录常量
~~将所有出现路径的地方用目录常量代替
C 框架初始类
目前,入口文件内实现的功能加多,将原来入口文件的功能,放到一个专门的类中来完成,而入口文件的各个功能,由该类的各个方法来实现,这个类一般也叫作框架初始化类,也叫作框架类。
入口文件还未实现自动加载,需要手动引入框架类文件.
~~框架初始类的功能代码
6.从框架初始类到配置文件
在项目开发中,很多参数都是在脚本中使用,如数据库的相关参数直接写在了代码中,为了管理方便,建立相关的配置文件管理这些参数。
每个不同的项目都有不同的配置参数,所以将他们放在App目录下。
在框架类中定义配置文件的目录常量
配置文件管理
在框架类中增加载入配置文件的操作
应用配置参数
7.数据库扩展的选择--引入PDO
引入pdo,用户可以自己选择到底是使用MySQL扩展还是PDO扩展,只需要在配置文件中进行配置就行了,而不需要修改项目中的其他的任何代码,实现无缝切换。
封装MySQLDB类和PDODB类,让二者都行实现相同的接口。
修改配置文件
在基础模型类中选择数据库类文件
在Frame目录下创建dao子目录,存放dao层的相关类和接口。注意修改目录常量。
在dao目录创建I_DAO.interface.php
让MySQLDB类实现这个接口
在dao目录创建PDODB.class.php,并实现相关方法
8.从控制器类到视图--引入Smarty
Smarty是属于外部提供的功能(插件),我们一般的做法是将其放到一个专门的目录里面,该目录可以命名为Vendor,也可以叫作Tools
A 配置Smarty
在根目录下创建Vendor目录,复制Smarty核心文件
设置目录常量和自动加载
B 在基础控制器中引入Smarty
C 在代码中引用Smarty
Smarty常用的两个方法
assign:分配变量。display:输出模板。
上述代码无法执行成功,因为smarty暂时还不知道stu_v.html文件目录。即还没有为Smarty设置默认的模板目录,还需要继续在基础控制器类里面设置。
~设置Smarty默认的模板目录:
规定视图按照所属的控制器再次进行分类,就是在视图View目录下,再次建立相应的控制器的名称作为子目录,然后将其对应的视图文件放到不同的子目录下。
~~优化编译目录
Smarty默认的编译目录是templates_c,所有的编译文件都在里面,比较混乱,而且放在根目录下也不合适,应该加以优化处理。
首先,我们应该将编译目录跟各个平台下的View目录同级,名字叫作View_c,并且和View一样也可以使用控制器作为子目录!
~~视图文件中使用分配的变量输出
~~优化Smarty对象的调用方式
在基础控制器中封装两个方法,就每次就可以直接使用$this->assign()和$this->display()两个方法
综上,一个基础MVC框架就算开发完成了。
三、MVC框架在开发中应用与优化(后台开发)
1.从基础代码文件到项目开发文件(初始化项目)
A 项目搭建
创建项目目录为根目录 =》nginx添加项目配置 =》 域名配置 => 数据库配置
B 移植mvc框架
复制框架代码,修改配置文件
C 根目录下创建public目录作为平台划分
在public划分平台home和back
前台和后台存放各自的css,image和js文件
增加新创建文件夹的目录常量。
除了public目录和入口文件,其余目录设置不能直接访问。在.htaccess中设置
2.实现后台登录
A 后台登录的业务开发
创建admin相关的mvc,AdminController、AdminModel、admin视图目录
开始开发。
B 封装跳转动作
分成直接跳转和刷新(提示)跳转,一般如果验证成功,就直接跳转,如果验证失败,就给出提示之后再进行跳转
在基础控制器类中定义jump方法。
C.引入其他功能,Vender中封装验证码类
在真实的项目中,验证码可以作为外部的插件直接引入,所以这里可以将验证码类放到Vendor目录下。
流程步骤:
创建类文件 =》增加类文件的自动加载 =》完善验证码类的逻辑 =》 配置文件中关联验证码类
项目中使用
D.平台控制器的引入,防止用户翻墙(必须登录)
让所有的业务控制器继承一个平台控制器,平台控制器中定义了判断用户信息的代码。
构造方法中调用
列出不需要验证的页面
E 数据接收的封装
基础控制器中封装过滤数据的方法 request。
由于对用户提交的数据在进行过滤的时候使用的比较多,操作起来比较麻烦,可以在基础控制器中增加一个专门过滤用户数据的方法。
~~ 防止SQL注入
A 概述
用户在进行一些数据库的操作,如表单提交,通过输入特殊的字符对sql产生了影响。
利用sql拼接如 ’ or 1 #
B 解决方案
对进来的数据进行过滤筛选处理。
将输入的字符串中带有引号的添加反斜杠,使用php函数addslashes()。
addslashes() 函数返回在预定义的字符前添加反斜杠的字符串。
3.后台首页功能,后台退出功能
4.信息分类管理-无限级分类
A 无限极分类原理
在业务开发中,涉及到目录栏下还有分类。创建分类表,利用无限极分类实现。
创建分类表,并在表中增加一个pid字段代表其父类id,如果该分类是一级分类(主类别),就设置pid为0。
在实际项目中,先获取所有分类,再使用递归树状展示。
排序后的数据,根据level判断层数,用于输出
或者将子类数据放在children数组中,子类包含子类一直延续下去。
B 实现分类的增删改查
查询出所有的分类信息后,还无法显示出它们之间的主从信息,这时就需要引入无限分类机制。
5.后台内容添加功能
A 完善文章的增删改查功能
B 封装并应用文件上传类
C 在线编辑器Ckeditor引入
D 在线文件管理器Ckfinder
E 后天首页展示与封装分页类
6.前台首页展示
A 首页功能完善
导航输出一级分类
后台控制文章前台显示 is_recommend
站长信息功能
百度分享功能
最新最热文章
友情链接
首页文章分页显示
面包屑功能
浏览次数更新
上一篇下一篇功能
art_id = 10的上一篇
select * from bg_article where is_del=’0’ and cate_id=8 and where art_id < 10 order by art_id desc limit 1;
select * from bg_article where is_del=’0’ and cate_id=8 and where art_id < 10 order by art_id desc limit 1;
单页面功能
一个栏目下只有一个页面:关于我们,公司介绍,在线招聘,网站公告等
创建单独的分类目录存储单页面目录,绑定文章
公有代码提取
7.会员注册功能
8.评论管理
9 缩略图
A
有时候在项目中,由于排版的需要,在显示图片的时候,宽和高都不是很大,但是可能用户上传的图片却很大!所以可以根据项目排版的实际需要将原图生成相应的缩略图,以节省用户的传输带宽,提高用户的体验度
B 封装图像处理类