PHP项目开发实例(二)(未使用框架)
3.后台登录管理

要写2个控制器



后台其他控制器继承 BaseController,检验是否登录


登录验证



退出


4.项目安全
后台登录的操作实际上存在安全隐患,实际项目中要考虑的几个基本安全问题。
三个安全问题:1. 恶意攻击; 2. SQL注入;3. XSS攻击
(1)恶意攻击
get方式,通过url,dos攻击,通常是从硬件和网络的角度,防火墙。(程序员不用管)
post方式,通过表单提交,穷举法,恶意破解,灌水。从程序的角度来防止。可以使用验证码。
在登录页面显示验证码




(2)SQL注入
在请求的时候,输入一些特殊的字符,然后构造成可以执行的sql语句,达到攻击的目的。
POST请求 和 GET请求
A.POST请求 在没有进行 md5 加密的情况下
万能密码 xxx' or '1

Sql语句显示:
SELECT * FROM cz_admin WHERE admin_name = 'xxxx' AND password = 'xxx' or '1' LIMIT 1;
or 1 永远都是 true ,就会将一条管理员信息返回。
应对方法 MD5 加密

Sql语句显示:
SELECT * FROM cz_admin WHERE admin_name = 'xxxx' AND password = 'e747940143cedc0d7cc1f20c3cd47719' LIMIT 1
密码加密的原因:
防止万能密码攻击
保护用户的隐私
万能用户名 xxx' or 1#

Sql语句显示:
SELECT * FROM cz_admin WHERE admin_name = 'xxx' or 1#' AND password = 'b59c67bf196a4758191e42f76670ceba' LIMIT 1
#号后面全部被 注释掉 照样能顺利登陆
应对方法
用户名不要加密
关键是单引号,让单引号失效,可以将其转义,有以下两种方式:
在php的层面来转义,php提供 addslashes()函数;
在mysql的层面来转义,mysql扩展提供的mysql_real_escape_string()函数。

转义后,将单引号转义
SELECT * FROM cz_admin WHERE admin_name = 'xxx\' or 1#' AND password = 'b59c67bf196a4758191e42f76670ceba' LIMIT 1
结论:千万不要相信用户的输入,对用户的输入一定要做验证和处理。
B.GET请求
比如,删除商品分类的时候要传一个参数 cat_id
shop.com/index.php?p=admin&c=category&a=delete&cat_id=7 or 1
请求,拼接的sql语句如下:
delete form cz_category where cat_id = 7 or 1;
结果全部删除了,非常不安全。
应对方法
将cat_id 转成整型,将 7 or 1 整个当做一个整型
①强制转换,(int)变量 ,使用intval()函数
②隐式转化,让其参与运算,用+

(3)XSS攻击
XSS:CrossSite Script,跨站脚本攻击。
恶意攻击者往Web页面里插入恶意html和JavaScript代码,当用户浏览该页之时,嵌入其中Web里面的html和JavaScript代码会被执行,从而达到恶意攻击用户的特殊目的。

应对方法
本质,都是html标签惹的祸。
措施:对html标签进行实体转义,在php中,有两个函数可以完成这个功能:
htmlspecialchars()函数
htmlentities()函数


转义形式
空格: 版权: $copy; < : < ; >: >
(4) 定义辅助函数完成批量转义
array_map 将回调函数作用到给定数组的单元上
array_map(callable $callback,array $arr1[,array $.......]);


5.错误管理
保持良好的代码书写习惯是避免错误的有效途径。
使用 ①Echo + exit;②var_dump() + exit;③file_put_contents();来查看错误。
增加sql语句执行日志:使用file_put_contents()将sql语句写到日志文件中。
PHP_EOL:换行符 常量
Windows:\n\r
Linux: \n
Mac:\r



6.商品类型管理
① 明确目标:完成商品类型的增删该查(CRUD)
② 业务逻辑分析

③ 添加商品类型
控制器与上一篇中的CategoryController 基本一致
一控制器、一模型、一表,六个方法,三个视图!!!!!!



④显示商品类型




分页效果(重点)
分页原理:
假如,每页要显示3条,用pagesize,用current 来表示当前页数
第一页:SELECT * FROM shop.cz_goods_type order by type_id limit 0,3
第二页:SELECT * FROM shop.cz_goods_type order by type_id limit 3,3
第三页:SELECT * FROM shop.cz_goods_type order by type_id limit 6,3
......
第N页:
SELECT * FROM shop.cz_goods_type order by type_id limit (current-1)*pagesize , pagesize
要完成分页显示效果,需要结合两个模型,数据库模型和工具类模型
数据库模型,完成的是取数据的任务
工具类模型,完成的是显示分页信息,并提供上下页的链接,分页类。
① 数据库模型






7.商品属性管理
① 明确目标:完成商品扩展属性的增删该查(CRUD)
商品的属性分成两类:
通用属性,每个商品都具备的属性,如名称,价格,图片等,存放在goods表中
扩展属性,不同类型的商品它的属性是不同的,它是存放在goods_attr表中
② 业务逻辑分析

type_id:类型id,表明当前这个属性是属于哪个类型的。
atrr_type:属性的类型,通常有唯一、单选和多选之分,
attr_input_type:属性的输入类型,通常有文本框、下拉列表、文本域之分
attr_value:属性的可选值(默认值)
③添加属性
控制器与 TypeController 基本一致
一控制器、一模型、一表,六个方法,三个视图!!!!!!

商品属性管理的入口 在 商品类型 列表中 goods_type_list.html


添加属性





④显示属性列表
商品属性管理的入口 在 商品类型 列表中 goods_type_list.html,点击 商品属性 会传该类型的 id 过来



需要输出商品类型的名称,就要通过连表查询。
连表方式, 内联inner join; 左连接left join
凡是能够使用inner join的地方,完全可以使用left join。
能够使用left join的地方,不一定能使用inner join。
总结:所有的地方都可以使用left join



分页显示






然后需要给下拉列表注册onchange事件

[注意]:对于这种复杂的功能,要一步步分步实现。
8.商品管理
① 明确目标:完成商品的增删该查(CRUD)
② 业务逻辑分析

③显示添加页面
与其他控制器相同
一控制器、一模型、一表,六个方法,三个视图!!!!!!

先处理 商品添加




知识点:选择商品类型,显示它对应的所有的属性,并且以表单的形式。
使用局部 刷新技术,两种方式:①Ajax ② 使用iframe实现
iframe 的技术要点就是在 页面中 增加一个 新的窗口 ,然后使用 Js 改变 iframe 的 src请求地址,来请求后台接口,获取数据, 然后操作DOM ,将获取的 数据 显示在页面上,一般操作DOM 的 innerHTML ; 一般 iframe 隐藏起来, 而将 需要输出的数据 显示在需要的地方。
分部完成复杂的地方


下拉菜单 onchange 事件

第三步 getAttrs 方法



④添加商品
难点 多表插入(连表)




strtotime()函数:将所有的表示日期时间的字符串转成时间戳


六 前台功能

① 显示首页




②展示所有商品分页
难点(递归) 层层获取子类


需要将平行的二维数组转成包含关系的多维数组,如图:





③获取推荐商品
is_best 字段 在模型中定义一个方法,获取推荐商品
不要使用*,可以提高查询效率,节省资源;避免出现逻辑错误



总结
粗糙的跟着视频做了个项目,基本了解MVC框架的整体流程,对MVC操作有个基本了解。
从请求到从数据库取数据有个大概了解。
M,model,表示模型,完成具体的业务逻辑,V,view,表示视图,用来展示页面,C,controller,控制器,专门用来负责调度数据的。
难点:递归,数据库设计,小的知识点。
要不断复习各个知识点,熟悉MVC。
熟悉PHP 语法和书写规范。