博客项目(五)
封装分页类
回顾分页的步骤
- 获取总记录数 $rowscount=select count(*) from 表
- 求的总页码 $pagecount=ceil($rowscount/$pagesize)
- 获取当前页码($pageno) 点击分页页码传递当前页码值
- 求出$startno $startno=($pagesize-1)*$pagesize
- 查询当前页的数据 Select * from 表 limit $startno,$pagesize
封装分页类
分页类有两个功能
- 求分页需要的数据
- 拼接分页字符串
- 在Lib文件夹下创建Page.class.php页面
<?php
namespace Lib;
class Page{
private $rowscount; //总记录数
private $pagecount; //页面总数
private $pageno; //当前页码
public $pagesize; //页面大小
public $startno; //起始位置
public function __construct($rowscount,$pagesize) {
$this->initParam($rowscount, $pagesize);
}
//初始化分页数据
private function initParam($rowscount,$pagesize){
$this->rowscount=$rowscount; //总记录数
$this->pagesize=$pagesize; //页面大小
$this->pagecount=ceil($this->rowscount/$this->pagesize); //总页数
$this->pageno=isset($_REQUEST[‘pageno’])?(int)$_REQUEST[‘pageno’]:1; //当前页
if($this->pageno<1)
$this->pageno=1;
if($this->pageno>$this->pagecount)
$this->pageno= $this->pagecount;
$this->startno=($this->pageno-1)*$this->pagesize; //起始值
}
//拼接分页字符串
public function show(){
$url=’index.php?p=’.PLATFORM_NAME.’&c=’.CONTROLLER_NAME.’&a=’.ACTION_NAME.’&pageno=’;
$str='<div class=”panel-foot text-center”>’;
$str.='<ul class=”pagination”><li><a href=”‘.$url.($this->pageno-1).'”>上一页</a></li></ul>’;
$str.='<ul class=”pagination pagination-group”>’;
for($i=1;$i<=$this->pagecount;$i++){
if($i==$this->pageno)
$str.='<li class=”active”><a href=”‘.($url.$i).'”>’.$i.'</a></li>’;
else
$str.='<li><a href=”‘.($url.$i).'”>’.$i.'</a></li>’;
}
$str.='</ul>’;
$str.='<ul class=”pagination”><li><a href=”‘.$url.($this->pageno+1).'”>下一页</a></li></ul>’;
$str.='</div>’;
return $str;
}
}
- 更改ArticleModel模型
<?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);
}
/*
* 删除文章
* @param $ids string 删除id通过逗号连接的字符串
*/
public function deleteArticle($ids){
$sql=”update article set is_recycle=1 where art_id in ($ids)”;
return $this->mypdo->exec($sql);
}
/*
* 拼接查询的SQL语句
* @param $condition array 查询条件
* @param $is_list bool true:查询结果SQL,false:查询数量SQL
*/
private function createSQL($condition,$is_list=true){
if($is_list)
$sql= ‘select a.art_id,a.art_title,a.art_content,a.is_top,is_public,c.cat_name,a.art_time’;
else
$sql=’select count(*)’;
$sql.=’ 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’];
if($is_list)
$sql.=’ order by is_top desc,art_id desc’;
return $sql;
}
//通过条件获取满足条件的记录数
public function getArticleCount($condition){
$sql=$this->createSQL($condition,false);
return $this->mypdo->fetchColumn($sql);
}
//通过条件检索文章
public function getArticleListByCondition($condition,$startno,$pagesize){
$sql=$this->createSQL($condition,true);
$sql.=” limit $startno,$pagesize”;
return $this->mypdo->fetchAll($sql);
}
}
- 更改ArticleController控制器
namespace Controller\Admin;
class ArticleController extends \Controller\Admin\BaseController{
//显示文章列表
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();
$rowscount=$art_model->getArticleCount($data); //获取文章数量
$page=new \Lib\Page($rowscount, 1);
$list=$art_model->getArticleListByCondition($data,$page->startno,$page->pagesize);
$page_str=$page->show();
$this->smarty->assign(‘page_str’,$page_str);
$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’);
}
…
在视图页面art_list.html中,显示分页
封装错误提示
开发模式:错误显示在浏览器上,不用记录在日志中
运行模式:错误记录在日志中,不显示在浏览器上
- 在config.conf文件,通过degbug来设定开发模式和运行模式
- 在Framework中初始化错误显示方式
文本编辑器
常用的文本编辑器有:CKEditor,UEditor,KingEditor
CKEditor
第一步:下载ckeditor
第二步:解压,将ckeditor拷贝到Public目录下
第三步:将ckeditor核心文件引入到网页中
<script src=”/Public/ckeditor/ckeditor.js”></script>
<textarea name=”art_content” cols=”50″ rows=”5″ class=”input” id=”art_content” placeholder=”内容”></textarea>
<script type=”text/javascript”>
CKEDITOR.replace(‘art_content’);
</script>
注意:CkEditor不能上传图片,要配合CKFinder才能上传图片
运行结果
UEditor
UEditor是百度开发的文本编辑器,UM是UE的迷你版
第一步:解压UM,将解压的文件夹拷贝大Public目录下,并改名umeditor
第二步:在文件中引入UM的核心文件
设定文本编辑器的宽高
运行结果
KingEditor
第一步:解压KingEditor,并拷贝到Public目录下,改名kindeditor
第二步:引入核心文件
运行结果
首页显示
- 将静态资源拷贝到对应的目录中
控制器
- 在Controller/Home文件夹下创建BaseController.class.php页面(前台基础控制器)
<?php
/*
* 前台基础控制器
*/
namespace Controller\Home;
class BaseController extends \Core\Controller{
}
- 在Controller/Home文件夹下IndexController.class.php(首页控制器)
<?php
namespace Controller\Home;
class IndexController extends BaseController{
public function indexAction(){
$art_model=new \Model\ArticleModel();
$art_list=$art_model->getArticleList();
$label_list=$art_model->getLabel();
$this->smarty->assign(‘data’,array(
‘art_list’ => $art_list,
‘label_list’=>$label_list
));
$this->smarty->display(‘index.html’);
}
}
模型
更改ArticleModel.class.php
<?php
namespace Model;
class ArticleModel extends \Core\Model{
//获取article和category表、user表的数据
public function getArticleList(){
$sql= ‘select * from article a,category c,user u where a.cat_id=c.cat_id and u.user_id=a.user_id and is_recycle=0 and is_public=1 order by is_top desc,art_id desc’;
return $this->mypdo->fetchAll($sql);
}
//创建索引词
public function getLabel(){
$sql=”select art_label from article where is_public=1 and is_recycle=0″;
$rs= $this->mypdo->fetchAll($sql,’num’);
foreach($rs as $rows){
$result=preg_split(‘/,|,/’,$rows[0],0,PREG_SPLIT_NO_EMPTY);
foreach($result as $r){
$r= strtoupper($r);
if(isset($array[$r]))
$array[$r]++;
else
$array[$r]=1;
}
}
arsort($array); //保持原来的键,反向排序
return $array;
}
。。。
视图(index.html)
Config:
//应用程序配置
‘app’ => array(
‘upload_path’ => ‘./Public/Uploads/’,
‘upload_size’ => 1024*1024,
‘upload_type’ => array(‘image/jpeg’,’image/png’,’image/gif’),
‘default_platform’ => ‘home’,
‘default_controller’ => ‘Index’,
‘default_action’ => ‘index’,
‘secure_key’ => ‘123’, //秘钥
‘debug’ => false //开发模式
运行结果
需要用到的知识点(正则表达式)
显示文章列表
入口
对应的代码
模型(ArticleModel)
控制器(ArticleController)
视图(art_list.html)
运行结果
知识点
内容页
模型
无
控制器(ArticleController)
视图
运行结果
阅读数
点击文章标题,显示文章的时候阅读数就加1.
更改ArticleController控制器中的ArticleAction()方法
实现点赞
模型
视图(article.html)
控制器(ArticleController)
同理,可以实现踩一下(自己去完成)
上一篇和下一篇
模型(ArticleModel)
public function getArticlePrevOrNext($art_id,$prev){
if($prev){
$sql=”select * from article where art_id<$art_id and is_public=1 and is_recycle=0 order by art_id desc limit 1″;
}else{
$sql=”select * from article where art_id>$art_id and is_public=1 and is_recycle=0 order by art_id asc limit 1″;
}
return $this->mypdo->fetchRow($sql);
}
视图(article.html)
控制器(ArticleController)
发表评论
创建回复表
CREATE table reply(
reply_id int unsigned auto_increment primary key comment ‘回复id’,
reply_content text not null comment ‘回复内容’,
reply_time int unsigned not null comment ‘回复时间’,
art_id int unsigned not null comment ‘文章id’,
user_id int unsigned not null comment ‘用户id’,
parent_id int unsigned not null comment ‘父级id’
)engine=innodb charset=utf8 comment ‘评论表’
结构
发表主评论
模型
没有
视图(article.html)
控制器(ReplyController)
在文章页取出回复
模型(ReplyModel)
<?php
namespace Model;
class ReplyModel extends \Core\Model{
public function getReplyTree($art_id){
$sql=”select * from reply,user where reply.user_id=user.user_id and art_id=$art_id”;
$list= $this->mypdo->fetchAll($sql);
$list= $this->createTree($list);
return $list;
}
private function createTree($list,$parent_id=0,$deep=0){
static $tree=array();
foreach($list as $rows){
if($rows[‘parent_id’]==$parent_id){
$rows[‘deep’]=$deep;
$tree[]=$rows;
$this->createTree($list,$rows[‘reply_id’],$deep+1);
}
}
return $tree;
}
}
控制器(ArticleController)
视图(article..html)
运行结果
添加子回复
入口(article.html)
视图(addReply.html)
模型
无
控制器
运行结果
项目总结
结构参见“项目结构.png”文件
E-R图
E(Entity)实体
R(Relationship):关系
设计数据库的步骤
第一步:标识实体
第二步:标识实体的属性
可以将实体和实体的属性用E-R标识
绘制E-R图
完整的E-R图
第三步:将实体转成表名,将属性转成字段名
- 能够实现博客前台首页显示功能
- 能够实现博客前台文章列表功能
- 能够实现博客前台显示文章详情功能
- 能够实现博客文章的踩赞功能
- 能够实现博客文章的上一篇下一篇功能
- 能够实现博客文章的标签功能
- 能够完成文章列表的翻页功能
- 能够实现博客文章的评论功能
- 能够理解博客项目的主要功能
- 能够根据功能要求画出有关数据表的ER图
- 能够针对项目要求设计适当的数据表