一.项目搭建
ü 良好的项目结构
ü 统一的命名规范
ü 单一入口(所有的请求都是相对于index.php)
1.项目结构说明
每一个优秀的项目都有一个良好的项目结构。不是统一,合理即可。
项目根目录结构如下:
Application目录结构如下:
Controllers目录结构如下:
对应的,views的目录结构如下:
注意,模型是前后台共用的,只需要一个即可,无需区分。
Framework目录结构如下:
根据类的功能和重要程度,划分如下:
2.搭建过程
(1).编码规范说明---非常重要(加分项)
命名规范
1.一定要有注释---养成好习惯
真实的项目中,注释一般占到 50%。
2.一定要有统一的命名规范
文件名,
类文件,类名.class.php
普通php文件,比较简单,直接命名
类名、方法名、属性名
类名,使用大驼峰命名法则,首字母大写,后续的每个单词首字母大写,如GoodsController.
方法,使用小驼峰命名法则,首字母小写,后续的每个单词首字母大写,如addAction
属性,使用小驼峰命名/下划线式
函数名
按照php的来做,php中有如下两种:
ü 下划线式:var_dump, is_array,
ü 连写式:imagecreatetruecolor
选定,保持一致。
常量名
大写
命名一定要见名知意,简洁。
- 严格区分大小写
一定要注意,严格区分大小写。
4. 注意缩进,代码对齐
顺手的工具,
编辑器:建议使用sublime,不建议使用Dreamweaver。
浏览器:两种以上,建议使用chrome和firefox,不建议使用ie浏览器
(2).定义核心启动类---让项目run起来
第一版:
效率上有一些提升,但是没那么明显。
很多的框架和项目都是这么写的,流行的用法。
分析run方法中要完成的功能:
index.php?p=admin&c=goods&a=add
需要分析url,确定是哪个平台,哪个控制器,哪个方法。
然后实例化控制器,并调用方法
控制器在哪?模型在哪?工具类在哪?
主要完成三个功能:
ü 初始化功能,主要是定义项目的路径常量
ü 路由,说白了,就是实例化控制器,调用方法
ü 自动载入
a.Init方法定义
获取当前工作目录,使用getcwd函数
Cwd:current work directory
其中 DIRECTORY_SEPARATOR 表示路径分隔符,在不同的操作系统中解析为不同的符号
Windows:\
Linux:/
代码如下:
b.定义dispatch方法,如下:
c.自动加载
__autoload
要实现自动有两种方案
ü 直接使用__autoload,不能写在类里面
ü 使用spl_autoload_register将普通的函数(方法)注册为自动加载的。
在类中,只能使用第二种。
首先,需要定义一个方法,完成指定类的自动加载
其次,将load方法注册为自动加载的
注意,在类中如何来引用一个方法呢,表示是某个类的方法。
实际上,需要告诉我连个东西:
ü 哪个类
ü 哪个方法
是否可用一个参数(变量)表示多个内容,-----数组
也可以这么写:
d.定义一个控制器测试之
思考:整个的执行是怎样的?
(3).加载视图
[需求]:将后台首页显示出来
只需要一行代码即可。使用include包含
然后,修改静态资源的引用路径,
(4).定义核心控制器
在项目当中,肯定有很多个控制器,它们必然有相同的方法。
要达到代码重用的目的,需要将通用的功能提取到基础控制器中。
a.在哪儿定义
请问,基础控制器中是否处理了具体的业务逻辑。
基础控制器应该是属于框架的。
b.定义哪些方法
定义一个方法,实现操作完成之后的信息提示
如何完成页面的跳转
ü Php中header函数
ü Js中location.href属性
ü Html中的meta头
并且要提示信息---message.html
定义jump如下:
现在有了基础控制器,其他的控制器要继承自它,
同时还有,当前的控制器如何载入呢?
直接在init中载入
(5).载入数据库模型(有难度)
关于模型,分成两条线
ü 数据库模型
ü 工具类模型
先看数据库模型
此处,使用了mysqldb对象,如图所示:
有几个方法,如下:
getOne:获取第一条记录的第一个字段的值
getRow:获取一条记录,一维数组
getAll:获取所有记录,返回二维数组
由于在整个项目中,有很多模型,必然有公用的方法,需要将这些公用的方法提取出来,形成一个基础模型。
然后,在控制器实例化模型对象,调用该方法
还需要完善几个地方,
ü 载入基础model
ü 配置数据库信息
定义配置文件,需要参考model类的构造方法
定义配置文件如下:
最后,需要载入配置文件
参考model中的构造方法,如下:
在init方法中载入配置
还要载入一个msysql类,
最后浏览,效果如下:
其中,在实例化模型的时候,传递了一个参数,表示当前要操作的表名。
相应的,在模型中,可以使用table属性引用表名,如下:
(6).载入工具类和辅助函数
工具类模型的使用
[需求]:完成验证码的显示
首先,将captcha类拷贝到libraries目录下:
接下来需要在控制器引入并调用
问题:如何引入验证码类?
第三种加载方式,手动的按需加载,通过调用一个方法,在需要的时候加载。
需要在基础控制器增加两个方法如下:
在indexController中定义code方法如下:
对应的,需要将字体文件拷贝到项目根目录之下,如下:
3.框架总结
核心思想:
Mvc的思想,对照mvc图
通过写代码来理解,掌握。
Oop:使用面向对象的方式 95%以上的代码都是以类的形式出现的。
如果已经搭建好框架了,接下来就只需要在application中编写代码就可以了
只需要按照mvc的套路来写,三板斧。
在框架中使用的三种加载方式:
ü 自动载入,application中的controller和model
ü 手动强制载入,在init中载入的,针对那些在整个项目中必不可少的类,如controller、model等
ü 手动按需载入,针对只是在某些模块中需要用到的类,如文件上传类,图像处理类
分成两块
ü Application:controllers和models文件夹固定,结构永远不变,文件名也是固定的,可以做到以不变应万变。
ü Framework:它的结构相对来说是无法固定的,没有办法做到以不变应万变。所以针对这种情况,就不使用自动加载,手动加载,要根据类的使用频率决定是强制加载还是按需加载。
数据库设计
重要程度:*****
难度:*****
1.数据库设计要点分析
ü Mysql数据类型
ü 表间关系
A.数据类型
Mysql数据类型有哪些?
ü 数值类型,整数(tinyint、smallint、mediumint、int、bigint)、小数(float、decimal)
ü 字符串类型,char、varchar、text,enum,set
ü 日期时间类型,date,time,datetime,timestamp
Msyql没有布尔类型。如何表示布尔类型呢?
有两种解决方案
ü 数值,tinyint,应用比较广泛
ü 字符串,enum
在php编程中,对于时间,实际上使用比较多的是int。
对于表中的每一个字段,要选用最合适的数据类型。
B.表间关系(有难度)
表与表的 什么关系?
A表和B表
A表中的记录和b表中的记录有哪些关系?
有三种:
ü 一对一
ü 一对多(多对一)
ü 多对多(重点)
如果a表中的一条记录,对应到b中只有一条,反之亦然,一对一。
如果a表中的一条记录,对应到b中有n条,反之,b表中的一条记录对应到a表中是一条,一对多。
如果a表中的一条记录,对应到b中有n条,反之,b表中的一条记录对应到a表中是n条,多对多。
一般来说,一对一出现比较少。一对多是最多的,多对多是最难的。
对于多对多的情况,我们是新增一张表,将一个多对多的关系转化成两个一对多的关系。
2.商品模块数据库设计
首先需要从商品出发。核心就是商品。
图片的保存分成两个部分
ü 图片文件本身,它保存在服务器的某个目录下
ü 将图片的地址保存到表中,就是字符串。
一对多的表设计
对多对表设计
关于商品的规格参数。
不同类型的商品,其规格参数不同。
如何保存这些信息?
直接使用一个字段保存是无法实现的。
只能用多个字段,每一个字段可以用一条记录保存。
商品的属性分成两大类:
ü 通用属性:所有的商品都具备的属性,如名称,价格,图片等。
ü 扩展属性,不同类型的商品,其扩展属性是不同的,如手机有分辨率、像素、摄像头等,而服装有尺码、季节、材质,而书有出版社,作者。
商品和扩展属性(规格参数)之间的关系---- 多对多
一个商品有多少个扩展属性 n个
一个扩展属性 被多少商品拥有 n个
隐含这个一个内容,就是扩展属性作为单独的信息来保存的。
首先,有一张表就是扩展属性表。
最后的设计如下: