博客项目(四)
文章表
drop table if exists article;
create table if not exists article(
art_id int unsigned auto_increment primary key comment ‘文章id’,
art_title varchar(50) not null comment ‘文章标题’,
art_content mediumtext not null comment ‘文章内容’,
art_label text not null comment ‘文章标签’,
art_time int not null comment ‘发表时间’,
art_click int unsigned default 0 not null comment ‘点击次数’,
art_up int unsigned default 0 not null comment ‘点赞次数’,
is_top tinyint not null default 0 comment ‘是否置顶’,
is_public tinyint not null default 0 comment ‘是否公开’,
is_recycle tinyint not null default 0 comment ‘是否在回收站’,
user_id int unsigned not null comment ‘用户id’,
cat_id int unsigned not null comment ‘类别id’
)engine=innodb charset=utf8 comment ‘文章表’;
表结构如下
添加文章
显示添加文章的界面
模型
无
控制器(在Controller\Admin文件夹下创建ArticleController.class.php)
视图(article_add.html)
注意:将表单元素的名称改成与数据库字段名一致
添加文章的入口
- 在menu.html页面中
- 入口位置(article_list.html)
实现添加文章的逻辑
模型
无
视图
无
控制器
多学一招:如果将表单元素的名字改成和字段名一致,可以简化代码量,但同时也将字段名暴露出来,我们可以通过关联数组将表单元素的名称和字段名建立映射,就可以解决字段暴露问题。
array(
‘title’ => ‘art_title’,
‘content’ => ‘art_cotnent’
)
显示文章列表
知识点
内连接语法
方法一:select * from 表1 inner join 表2 on 表1.公共字段=表2.公共字段
方法二:select * from 表1,表2 where 表1.公共字段=表2.公共字段
代码实现
模型(在Model文件夹创建ArticleModel.class.php)【获取不在回收站中的指定的字段数据。】
<?php
namespace Model;
class ArticleModel extends \Core\Model{
//获取article和category表的数据
public function getArticleList(){
$sql= ‘select a.art_id,a.art_title,a.is_top,is_public,c.cat_name,a.art_time from article a,category c where a.cat_id=c.cat_id and is_recycle=0 order by is_top desc,art_id desc’;
return $this->mypdo->fetchAll($sql);
}
}
控制器(ArticleController)
视图(article_list.html)
运行结果
修改文章
显示修改页面
模型
无
控制器(ArticleController)
视图(article_edit.html):将article_add.html复制一份改名为article_edit.html
实现修改业务
模型
无
视图
无
控制器(ArticleController)
删除文章
将文章的is_recycle字段的值变成1。
视图(article_list.html)
删除一条记录
批量删除
模型(ArticleModel)
控制器(ArticleController)
置顶、取消置顶
模型
无
视图(article_list.html)
控制器(ArticleController)
检索文章
显示检索文章的页面
控制器
视图(article_list.html)
模型
无
运行结果
完成检索逻辑
难点在于拼接SQL语句
模型(ArticleModel)
public function getArticleListByCondition($condition){
//拼接SQL查询语句
$sql= ‘select a.art_id,a.art_title,a.is_top,is_public,c.cat_name,a.art_time from article a,category c where a.cat_id=c.cat_id and is_recycle=0 and user_id=’.$_SESSION[‘user’][‘user_id’];
/*************通过类别查找************/
$cat_array=array(); // 保存类别id数组
if(isset($condition[‘cat_id’])){
$cat_id=$condition[‘cat_id’]; //选中的cat_id
$cat_model=new \Model\CategoryModel();
$sub_cat=$cat_model->getCategoryTree($cat_id); //获取cat_id的子级
foreach ($sub_cat as $rows){ //子级下面所有cat_id
$cat_array[]=$rows[‘cat_id’];
}
$cat_array[]=$cat_id; //当前cat_id和所有的子级cat_id数组
$cat_ids=implode(‘,’, $cat_array); //将cat_id数组转成逗号连接的字符串
if($cat_ids!=”)
$sql.=” and c.cat_id in ($cat_ids)”;
}
/*************通过标题查找************/
if(isset($condition[‘title’]))
$sql.=” and art_title like ‘%{$condition[‘title’]}%'”;
/*************通过内容查找************/
if(isset($condition[‘content’]))
$sql.=” and art_content like ‘%{$condition[‘content’]}%'”;
/*************通过是否公开查找************/
if(isset($condition[‘is_public’]))
$sql.=” and is_public=”.$condition[‘is_public’];
/*************通过是否置顶查找************/
if(isset($condition[‘is_top’]))
$sql.=” and is_top=”.$condition[‘is_top’];
$sql.=’ order by is_top desc,art_id desc’;
return $this->mypdo->fetchAll($sql);
}
视图
无
控制器(ArticleController),更改listAction()方法
public function listAction(){
$data=array(); //条件数组
if(!empty($_POST)){
//去除提交值的空格
foreach($_POST as $k=>$v){
if(trim($v)==”)
continue;
$data[$k]=trim($v);
}
}
$art_model=new \Model\ArticleModel();
$list=$art_model->getArticleListByCondition($data);
$cat_model=new \Model\CategoryModel();
$cat_list=$cat_model->getCategoryTree();
$this->smarty->assign(‘cat_list’,$cat_list);
$this->smarty->assign(‘list’,$list);
$this->smarty->display(‘article_list.html’);
}
防止XSS攻击
原理
解决方案:
方法一:将<和>转成实体< >
方法二:将<script替换成< script
在项目中解决
在插入数据的方法中,将每个值做字符串替换
作业
完成“回收站”功能,打开回收站,可以将回收站的文章删除和恢复。