关于MVC,先上图:
- 良好的项目结构
- 统一的命名规范
- 单一入口(所有的请求都是相对于index.php)
1.项目结构说明
每一个优秀的项目都有一个良好的项目结构。不是统一,合理即可。
项目根目录结构如下:
Application目录结构如下:
Controllers目录结构如下:
对应的,views的目录结构如下:
注意,模型是前后台共用的,只需要一个即可,无需区分。
Framework目录结构如下:
根据类的功能和重要程度,划分如下:
Public目录结构如下:
2.搭建过程
2.1.编码规范说明
2.1.1命名规范
1.一定要有注释—养成好习惯
真实的项目中,注释一般占到 50%。
2.一定要有统一的命名规范
文件名,类文件
类名.class.php
普通php文件,比较简单,直接命名
类名、方法名、属性名
类名,使用大驼峰命名法则,首字母大写,后续的每个单词首字母大写,如GoodsController.
方法,使用小驼峰命名法则,首字母小写,后续的每个单词首字母大写,如addAction
属性,使用小驼峰命名/下划线式
函数名
按照php的来做,php中有如下两种:
下划线式:var_dump, is_array,
连写式:imagecreatetruecolor
选定,保持一致。
常量名
大写
命名一定要见名知意,简洁。
3.严格区分大小写
一定要注意,严格区分大小写。
4. 注意缩进,代码对齐
2.1.2顺手的工具
编辑器:建议使用sublime,不建议使用Dreamweaver。
浏览器:两种以上,建议使用chrome和firefox,不建议使用ie浏览器
2.2定义核心启动类—让项目run起来
第一版:
第二版,新的方法,如下:
效率上有一些提升,但是没那么明显。
很多的框架和项目都是这么写的,流行的用法。
分析run方法中要完成的功能:
index.php?p=admin&c=goods&a=add
需要分析url,确定是哪个平台,哪个控制器,哪个方法。
然后实例化控制器,并调用方法
控制器在哪?模型在哪?工具类在哪?
主要完成三个功能:
- 初始化功能,主要是定义项目的路径常量
- 路由,说白了,就是实例化控制器,调用方法
- 自动载入
2.2.1init方法定义
获取当前工作目录,使用getcwd函数
echo getcwd();
cwd:current work directory
DIRECTORY_SEPARATOR 表示路径分隔符,在不同的操作系统中解析为不同的符号
Windows:\
Linux:/
代码如下:
2.2.2 定义dispatch方法
2.2.3 自动加载
系统函数:__autoload()
要实现自动有两种方案
1.直接使用__autoload,不能写在类里面
2.使用spl_autoload_register将普通的函数(方法)注册为自动加载的。
在类中,只能使用第二种。
首先,需要定义一个方法,完成指定类的自动加载
其次,将load方法注册为自动加载的
注意,在类中如何来引用一个方法呢,表示是某个类的方法。
实际上,需要告诉我2个东西:
哪个类
哪个方法
是否可用一个参数(变量)表示多个内容,—–数组
也可以这么写:
d.定义一个控制器测试之
思考:整个的执行是怎样的?
2.3 加载视图
[需求]:将后台首页显示出来
只需要一行代码即可。使用include包含
对应的,将视图页面拷贝到 views/admin下。
这里不是必须把资源文件放在public文件夹下,也可以放在application/views/admin下。
然后,修改静态资源的引用路径,
如果使用php的常量路径,会怎么样?
原因在于:出于安全的考虑,浏览器是不能访问本地资源的。
但可以使用相对站点的绝对路径。
2.4定义核心控制器
在项目当中,肯定有很多个控制器,它们必然有相同的方法。
要达到代码重用的目的,需要将通用的功能提取到基础控制器中。
2.4.1在哪儿定义
基础控制器不处理具体的业务逻辑。基础控制器是属于框架的。
2.4.2 定义哪些方法
定义一个方法,实现操作完成之后的信息提示
如何完成页面的跳转
- Php中header函数
- Js中location.href属性
- Html中的meta头
并且要提示信息—message.html
定义jump如下:
现在有了基础控制器,其他的控制器要继承自它,
同时还有,当前的控制器如何载入呢?
直接在init中载入
还有一些,稍后定义。
2.5 载入数据库模型
关于模型,分成两条线
- 数据库模型
- 工具类模型
先看数据库模型
此处,使用了mysqldb对象,如图所示:
有几个方法,如下:
- getOne:获取第一条记录的第一个字段的值
- getRow:获取一条记录,一维数组
- getAll:获取所有记录,返回二维数组
由于在整个项目中,有很多模型,必然有公用的方法,需要将这些公用的方法提取出来,形成一个基础模型。
常用的方法如下:
- Insert:自动插入记录
- update:自动更新,一定要有主键
- delete:自动删除
- selectByPk:通过主键获取记录的信息
- total:获取总的记录数
自己定义模型,要继承在基础模型
目标:将admin的数据显示在页面上
然后,在控制器实例化模型对象,调用该方法
还需要完善几个地方,
- 载入基础model
- 配置数据库信息
定义配置文件,需要参考model类的构造方法
定义配置文件如下:
最后,需要载入配置文件
参考model中的构造方法,如下:
在init方法中载入配置
还要载入一个msysql类,
其中,在实例化模型的时候,传递了一个参数,表示当前要操作的表名。
相应的,在模型中,可以使用table属性引用表名,如下:
2.6 载入工具类和辅助函数
工具类模型的使用
[需求]:完成验证码的显示
首先,将captcha类拷贝到libraries目录下:
接下来需要在控制器引入并调用
问题:如何引入验证码类?
第三种加载方式,手动的按需加载,通过调用一个方法,在需要的时候加载。
需要在基础控制器增加两个方法如下:
在indexController中定义code方法如下:
对应的,需要将字体文件拷贝到项目根目录之下,如下:
3.框架总结
框架结构:
如果已经搭建好框架了,接下来就只需要在application中编写代码就可以了
只需要按照mvc的套路来写,三板斧。
在框架中使用的三种加载方式:
自动载入,application中的controller和model
手动强制载入,在init中载入的,针对那些在整个项目中必不可少的类,如controller、model等
手动按需载入,针对只是在某些模块中需要用到的类,如文件上传类,图像处理类
分成两块
Application:controllers和models文件夹固定,结构永远不变,文件名也是固定的,可以做到以不变应万变。
Framework:它的结构相对来说是无法固定的,没有办法做到以不变应万变。所以针对这种情况,就不使用自动加载,手动加载,要根据类的使用频率决定是强制加载还是按需加载。