博客源码:https://github.com/pleated/blog
源码地址:https://github.com/xialeistudio/thinkphp-inaction/tree/master/blog
功能
- 管理员登陆,修改密码,退出登录
- 文章分类添加,编辑,删除。
- 文章添加,编辑,删除。
- 发表,管理评论
- 添加,删除,展示友情链接
创建数据表
CREATE TABLE blog_admin (`adminId` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(20) NOT NULL COMMENT '账号', `password` char(32) NOT NULL COMMENT '密码', `createdAt` int(10) NOT NULL COMMENT '添加时间',`loginAt` int(11) NOT NULL DEFAULT '0' COMMENT '最近登录时间',`loginIp`varchar(15) NOT NULL DEFAULT '' COMMENT '最近登录IP',PRIMARY KEY (`adminId`), KEY `createdAt` (`createdAt`),KEY `account`(`username`,`password`)) ENGINE=InnoDB AUTO_INCREMENT=2 DEFAULT CHARSET=utf8mb4;
INSERT INTO `blog_admin` VALUES ('1', 'admin', '6f1779da8462d85c012588fb73a2efb7', '0', '0', '');//添加管理员账号密码admin和admin
CREATE TABLE blog_article (`articleId` int(11) NOT NULL AUTO_INCREMENT,`title` varchar(40) NOT NULL COMMENT '标题', `description` varchar(100) NOT NULL DEFAULT '' COMMENT '简介',`image` varchar(128) NOT NULL DEFAULT '' COMMENT '封面图片',`hits` int(11) NOT NULL DEFAULT '0' COMMENT '点击数',`createdAt` int(11) NOT NULL COMMENT '添加时间',`updateAt` int(11) NOT NULL DEFAULT '0' COMMENT '更新时间',`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态',`sort` int(11) NOT NULL DEFAULT '0' COMMENT '排序',`content` text NOT NULL COMMENT '文章内容',`categoryId` int(10) unsigned NOT NULL,PRIMARY KEY (`articleId`),KEY `hit` (`hits`),KEY `createdAt` (`createdAt`),KEY `status` (`status`),KEY `sort` (`sort`),KEY `fk_blog_article_blog_category_idx` (`categoryId`),CONSTRAINT `fk_blog_article_blog_category` FOREIGN KEY (`categoryId`) REFERENCES `blog_category` (`categoryId`) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE blog_category (`categoryId` int(10) unsigned NOT NULL AUTO_INCREMENT, `name` varchar(20) NOT NULL COMMENT '分类名称',`isNav` tinyint(1) NOT NULL DEFAULT '1' COMMENT '是否显示在导航栏',`total` int(11) NOT NULL DEFAULT '0' COMMENT '文章总数',`sort` tinyint(4) NOT NULL DEFAULT '0' COMMENT '排序',PRIMARY KEY (`categoryId`),KEY `sort` (`total`),KEY `total` (`total`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE blog_comment (`commentId` int(11) NOT NULL AUTO_INCREMENT,`nickname` varchar(20) NOT NULL COMMENT '昵称',`createdAt` int(11) NOT NULL COMMENT '评论时间',`createdIp` varchar(15) NOT NULL COMMENT 'ip地址',`content` text NOT NULL COMMENT '评论内容',`articleId` int(11) NOT NULL,PRIMARY KEY (`commentId`),KEY `created` (`createdAt`),KEY `fk_blog_comment_blog_article1_idx` (`articleId`),CONSTRAINT `fk_blog_comment_blog_article1` FOREIGN KEY (`articleId`) REFERENCES `blog_article` (`articleId`) ON DELETE NO ACTION ON UPDATE NO ACTION) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
CREATE TABLE blog_link( `linkId` int(11) NOT NULL AUTO_INCREMENT `name` varchar(20) NOT NULL COMMENT '站点名称',`link` varchar(100) NOT NULL COMMENT '链接地址',`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态',`sort` int(11) NOT NULL DEFAULT '0' COMMENT '排序',PRIMARY KEY (`linkId`),KEY `sort` (`sort`),KEY `status` (`status`)) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
thinkphp\blog\Application\Admin模块
这是后台管理模块,需要管理文章,分类,评论,友情链接等功能。
①thinkphp\blog\Application\Admin\Controller
是这些功能的控制器:
ArticleController.class.php 文章控制器
CategoryController.class.php 分类控制器
CommentController.class.php 评论控制器
LinkController.class.php 友情链接控制器
admin模块是受保护的模块,所以这四个控制器许登陆后才能正常访问,在同级目录下创建BaseController.class.php
控制器处理登录检测,需要进行权限检测的控制器继承它就行。例如:thinkphp\blog\index.php\admin\index\login
调用的是blog\Application\Admin\Controller\IndexController.class.php
//U('index/admin/index/login')
②分页处理
数据量不可预测,须在列表页进行分页处理,在需要分页的功能的控制器
里面加入分页代码
③文章分类
文章是分类的,在读取文章列表的时候将分类信息同时查询处理,在这里使用ThinkPHP提供的ViewModel,在thinkphp\blog\Application\Common\Model\ArticleCategoryViewModel.class.php
实现
④文件上传thinkphp\blog\Application\Admin\View\Common\upload.html
中定义上传功能,然后在thinkphp\blog\Application\Admin\Controller\IndexController.class.php
控制器中添加upload方法,在thinkphp\blog\Application\Admin\View\Article\post.html
中使用<include file="Common:upload"/>
引用
thinkphp\blog\Application\Common模块
①分类处理
此模块是公用模块,其他模块公用的功能可以放在该模块下,例如上面提到的③文章分类
是公用Model,所以放在Common/Model
下。
文章分类时有'isNav'字段,这是用来标识分类是否是导航栏中的分类:
status为1:读取属于导航栏的分类
status为0:读取不属于导航栏的分类
读取全部分类
以上需求返回值是一致的,将以上三个需求封装成一个函数,根据传入的status决定返回数据thinkphp\blog\Application\Common\Common\function.php
function getCategory($isNav = -1)
{
$map = array();
if ($isNav > -1)
{
$map['isNav'] = $isNav;
}
$model = new \Think\Model('Category');
return $model->where($map)->order('sort DESC')->select();
}//当给定的status>-1时添加一个过滤参数,=-1则不添加。
②友情链接列表
友情链接是通过函数来定义,前端通过函数调用。thinkphp\blog\Application\Common\Common\function.php
③数据库字段大小写
在使用ThinkPHP的Model进行数据库操作时,返回的数据键名是大写的。
编辑'thinkphp\blog\Application\Common\Conf\db.php',在其中添加
'DB_PARAMS' => array(
PDO::ATTR_CASE => PDO::CASE_NATURAL
)//控制大小写
Home模块
①前台布局
此模块用到了ThinkPHP的模板布局功能
在thinkphp\blog\Application\Common\Conf\config.php
添加'LAYOUT_ON' => true
,开启模板布局,ThinkPHP会默认使用名为“layout”的模板,在thinkphp\blog\Application\Home\View\layout.html
文件。(代码就不贴了,github中都有),在此布局文件用到了模板常量,而ThinkPHP自带的模板常量只有_PUBLIC_
,所以需在thinkphp\blog\Application\Home\Conf\config.php
中单独定义
return array(
'TMPL_PARSE_STRING' => array(
'__VENDOR__' => '/thinkphp/blog/public/vendor',
'__JS__' => '/thinkphp/blog/public/home/js',
'__CSS__' => '/thinkphp/blog/public/home/css',
'__IMAGE__' => '/thinkphp/blog/public/home/images'
),
我的项目是部署在localhost/thinkphp中,在定义模板常量的时候需要写全。
公用部分用vendor目录,
导航栏,友情链接等这几个功能都是公用功能,在模板文件使用调用thinkphp\blog\Application\Common\Common\function.php
中的getCategory
和getLinks
函数,不会出现读取不到数据的问题。
②评论间隔处理
使用缓存来做评论间隔处理thinkphp\blog\Application\Home\Controller\IndexController.class.php
里的comment()方法执行此操作。$id是被评论文章的ID,$key = get_client_ip() . '-view-article-' . $id;
是使用ID+IP的方式识别当前评论用户,若S函数返回值不为空,则缓存有效期内已经评论过,返回错误信息,若评论成功,则使用当前$key写入缓存
③Ajax评论
在文章页评论功能的开发中使用Ajax
, 在thinkphp\blog\Application\Home\View\Index\article.html
中。提交的时候使用$.post
方式提交。在回调函数中需要先判断是否出错,如果出错则显示错误信息,否则显示该评论。评论使用的是jQuery的prepend方法。因最新的评论在最前面,须将生成的html添加到最前面。
其他总结
入口
index.php
文件调用thinkphp\blog\Application\Home\Controller\IndexController.class.php
和thinkphp\blog\Application\Common\Model\ArticleCategoryViewModel.class.php。thinkphp\blog\Application\Common\Conf\config.php
应用配置文件也就是调用所有模块之前都会首先加载的公共配置文件thinkphp\blog\Application\Admin\View\..
这个文件中index.html
是后台的编写各个模块的列表,post.html
则是发表页面前台Home模块用到了ThinkPHP的模块布局功能。编辑
thinkphp\blog\Application\Common\Conf\config.php
文件,默认调用thinkphp\blog\Application\Home\View
下的layout.html
文件该布局用到了常量模块,而ThinkPHP自带的模块常量只有PUBLIC,所以需在
thinkphp\blog\Application\Common\Conf\config.php
中单独定义,并在thinkphp\blog\Application\Home\Conf\config.php
中调用需要的布局。