全面掌握ThinkPHP 6.x核心特性,从零开始构建企业级内容管理系统
ThinkPHP 6.x 框架简介
ThinkPHP是一款免费开源的轻量级PHP开发框架,遵循Apache2开源协议发布。ThinkPHP 6.x是最新版本,相比之前的5.x版本进行了大量重构和优化,提供了更好的性能、更简洁的API和更现代的开发体验。
ThinkPHP 6.x 新特性
- 支持PSR标准,完全遵循PSR-2、PSR-4、PSR-7、PSR-11、PSR-15和PSR-16规范
- 采用中间件架构,更灵活的请求处理流程
- 依赖注入和支持容器管理,更好的解耦设计
- 改进的路由系统,支持更灵活的路由定义和分组
- 模板引擎分离,可以更灵活选择模板引擎
- 更好的IDE支持,完善的注释和代码提示
开发环境搭建
环境要求
PHP >= 7.1.0
Composer
PDO PHP Extension
MBstring PHP Extension
安装ThinkPHP 6
使用Composer创建项目:
composer create-project topthink/think tp6-cms
cd tp6-cms
项目结构
tp6-cms/
├── app/ // 应用目录
│ ├── controller/ // 控制器目录
│ ├── model/ // 模型目录
│ ├── view/ // 视图目录
│ └── ...
├── config/ // 配置目录
├── public/ // web入口目录
├── route/ // 路由定义目录
├── runtime/ // 运行时目录
├── vendor/ // Composer依赖目录
└── extend/ // 扩展类库目录
CMS系统架构设计
数据库设计
创建内容管理系统所需的数据表:
-- 管理员表
CREATE TABLE `cms_admin` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`username` varchar(50) NOT NULL DEFAULT '' COMMENT '用户名',
`password` varchar(255) NOT NULL DEFAULT '' COMMENT '密码',
`email` varchar(100) NOT NULL DEFAULT '' COMMENT '邮箱',
`login_time` int(11) DEFAULT NULL COMMENT '登录时间',
`login_ip` varchar(50) DEFAULT NULL COMMENT '登录IP',
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态:1正常,0禁用',
`create_time` int(11) DEFAULT NULL COMMENT '创建时间',
`update_time` int(11) DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`),
UNIQUE KEY `username` (`username`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='管理员表';
-- 栏目表
CREATE TABLE `cms_category` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(50) NOT NULL DEFAULT '' COMMENT '栏目名称',
`pid` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '父级ID',
`sort` int(11) NOT NULL DEFAULT '0' COMMENT '排序',
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态:1显示,0隐藏',
`create_time` int(11) DEFAULT NULL COMMENT '创建时间',
`update_time` int(11) DEFAULT NULL COMMENT '更新时间',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='栏目表';
-- 文章表
CREATE TABLE `cms_article` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`category_id` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '栏目ID',
`title` varchar(255) NOT NULL DEFAULT '' COMMENT '标题',
`content` longtext COMMENT '内容',
`author` varchar(50) DEFAULT '' COMMENT '作者',
`image` varchar(255) DEFAULT '' COMMENT '封面图',
`views` int(11) unsigned NOT NULL DEFAULT '0' COMMENT '浏览量',
`is_top` tinyint(1) NOT NULL DEFAULT '0' COMMENT '是否置顶:1是,0否',
`status` tinyint(1) NOT NULL DEFAULT '1' COMMENT '状态:1发布,0草稿',
`create_time` int(11) DEFAULT NULL COMMENT '创建时间',
`update_time` int(11) DEFAULT NULL COMMENT '更新时间',
`publish_time` int(11) DEFAULT NULL COMMENT '发布时间',
PRIMARY KEY (`id`),
KEY `category_id` (`category_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='文章表';
目录结构规划
app/
├── admin/ // 后台应用
│ ├── controller/ // 后台控制器
│ ├── model/ // 后台模型
│ └── view/ // 后台视图
├── common/ // 公共模块
│ ├── model/ // 公共模型
│ └── library/ // 公共类库
├── index/ // 前台应用
│ ├── controller/ // 前台控制器
│ ├── model/ // 前台模型
│ └── view/ // 前台视图
└── middleware/ // 应用中间件
核心功能模块实现
1. 后台登录模块
创建管理员模型:
<?php
namespace appadminmodel;
use thinkModel;
use thinkmodelconcernSoftDelete;
class Admin extends Model
{
use SoftDelete;
protected $name = 'cms_admin';
protected $autoWriteTimestamp = true;
protected $createTime = 'create_time';
protected $updateTime = 'update_time';
protected $deleteTime = 'delete_time';
protected $defaultSoftDelete = 0;
// 密码自动加密
public function setPasswordAttr($value)
{
return password_hash($value, PASSWORD_DEFAULT);
}
// 验证密码
public function verifyPassword($password, $hash)
{
return password_verify($password, $hash);
}
}
?>
创建登录控制器:
<?php
namespace appadmincontroller;
use thinkfacadeSession;
use appadminmodelAdmin;
class Login extends Base
{
// 显示登录页面
public function index()
{
if ($this->request->isPost()) {
$username = $this->request->param('username');
$password = $this->request->param('password');
$captcha = $this->request->param('captcha');
// 验证码验证
if (!captcha_check($captcha)) {
return $this->error('验证码错误');
}
// 管理员验证
$admin = Admin::where('username', $username)
->where('status', 1)
->find();
if (!$admin || !$admin->verifyPassword($password, $admin->password)) {
return $this->error('用户名或密码错误');
}
// 更新登录信息
$admin->login_time = time();
$admin->login_ip = $this->request->ip();
$admin->save();
// 设置Session
Session::set('admin_id', $admin->id);
Session::set('admin_username', $admin->username);
return $this->success('登录成功', url('admin/index/index'));
}
return $this->fetch();
}
// 退出登录
public function logout()
{
Session::delete('admin_id');
Session::delete('admin_username');
return $this->success('退出成功', url('admin/login/index'));
}
}
?>
2. 栏目管理模块
创建栏目模型:
<?php
namespace appadminmodel;
use thinkModel;
use thinkmodelconcernSoftDelete;
class Category extends Model
{
use SoftDelete;
protected $name = 'cms_category';
protected $autoWriteTimestamp = true;
protected $createTime = 'create_time';
protected $updateTime = 'update_time';
protected $deleteTime = 'delete_time';
protected $defaultSoftDelete = 0;
// 获取树形结构
public function getTreeList($status = null)
{
$where = [];
if ($status !== null) {
$where[] = ['status', '=', $status];
}
$list = $this->where($where)
->order('sort ASC, id ASC')
->select()
->toArray();
return $this->buildTree($list);
}
// 构建树形结构
protected function buildTree($items, $pid = 0)
{
$tree = [];
foreach ($items as $item) {
if ($item['pid'] == $pid) {
$children = $this->buildTree($items, $item['id']);
if ($children) {
$item['children'] = $children;
}
$tree[] = $item;
}
}
return $tree;
}
}
?>
3. 文章管理模块
创建文章模型:
<?php
namespace appadminmodel;
use thinkModel;
use thinkmodelconcernSoftDelete;
use appadminmodelCategory;
class Article extends Model
{
use SoftDelete;
protected $name = 'cms_article';
protected $autoWriteTimestamp = true;
protected $createTime = 'create_time';
protected $updateTime = 'update_time';
protected $deleteTime = 'delete_time';
protected $defaultSoftDelete = 0;
// 状态获取器
public function getStatusTextAttr($value, $data)
{
$status = [0 => '草稿', 1 => '发布'];
return $status[$data['status']] ?? '未知';
}
// 置顶状态获取器
public function getIsTopTextAttr($value, $data)
{
return $data['is_top'] ? '是' : '否';
}
// 关联栏目
public function category()
{
return $this->belongsTo(Category::class, 'category_id');
}
// 获取栏目名称
public function getCategoryNameAttr($value, $data)
{
$category = Category::find($data['category_id']);
return $category ? $category->name : '未分类';
}
}
?>
ThinkPHP高级特性应用
1. 中间件使用
创建后台认证中间件:
<?php
namespace appadminmiddleware;
use thinkfacadeSession;
class Auth
{
public function handle($request, Closure $next)
{
// 检查是否登录
if (!Session::has('admin_id')) {
if ($request->isAjax()) {
return json(['code' => 401, 'msg' => '请先登录']);
} else {
return redirect(url('admin/login/index'));
}
}
return $next($request);
}
}
?>
注册中间件:
// app/admin/middleware.php
return [
// 全局中间件
appadminmiddlewareAuth::class,
// 路由中间件别名
'alias' => [
'auth' => appadminmiddlewareAuth::class,
],
];
2. 验证器使用
创建文章验证器:
<?php
namespace appadminvalidate;
use thinkValidate;
class Article extends Validate
{
protected $rule = [
'category_id' => 'require|number',
'title' => 'require|max:255',
'content' => 'require',
'author' => 'max:50',
'status' => 'require|in:0,1',
'is_top' => 'require|in:0,1',
];
protected $message = [
'category_id.require' => '请选择栏目',
'category_id.number' => '栏目格式错误',
'title.require' => '标题不能为空',
'title.max' => '标题长度不能超过255个字符',
'content.require' => '内容不能为空',
'author.max' => '作者长度不能超过50个字符',
'status.require' => '状态不能为空',
'status.in' => '状态值错误',
'is_top.require' => '置顶状态不能为空',
'is_top.in' => '置顶状态值错误',
];
// 添加场景
protected $scene = [
'save' => ['category_id', 'title', 'content', 'author', 'status', 'is_top'],
'update' => ['category_id', 'title', 'content', 'author', 'status', 'is_top'],
];
}
?>
3. 服务层封装
创建文章服务类:
<?php
namespace appadminservice;
use thinkfacadeFilesystem;
use thinkfileUploadedFile;
use appadminmodelArticle as ArticleModel;
class ArticleService
{
// 保存文章
public function saveArticle($data, $id = null)
{
try {
if ($id) {
$article = ArticleModel::findOrFail($id);
$result = $article->save($data);
} else {
$article = new ArticleModel();
$result = $article->save($data);
}
return $result ? $article->id : false;
} catch (Exception $e) {
throw new Exception('保存文章失败: ' . $e->getMessage());
}
}
// 上传封面图
public function uploadImage(UploadedFile $file)
{
try {
// 验证文件
validate(['image' => 'fileSize:2048000|fileExt:jpg,jpeg,png,gif'])
->check(['image' => $file]);
// 保存文件
$savename = Filesystem::disk('public')
->putFile('article', $file);
return '/uploads/' . $savename;
} catch (thinkexceptionValidateException $e) {
throw new Exception($e->getMessage());
}
}
// 获取文章列表
public function getArticleList($page = 1, $limit = 15, $where = [])
{
$model = ArticleModel::with('category')
->where($where);
$list = $model->page($page, $limit)
->order('is_top DESC, publish_time DESC')
->select();
$total = $model->count();
return [
'list' => $list,
'total' => $total,
'page' => $page,
'limit' => $limit,
'pages' => ceil($total / $limit)
];
}
}
?>
性能优化与安全
1. 数据库优化
使用模型缓存:
<?php
namespace appadminmodel;
use thinkModel;
class Category extends Model
{
// 获取栏目列表(带缓存)
public function getCachedList()
{
return $this->where('status', 1)
->order('sort ASC, id ASC')
->cache('category_list', 3600)
->select();
}
}
?>
2. 缓存优化
使用Redis缓存:
// config/cache.php
return [
'default' => 'redis',
'stores' => [
'redis' => [
'type' => 'redis',
'host' => '127.0.0.1',
'port' => 6379,
'password' => '',
'select' => 0,
'timeout' => 0,
'persistent' => false,
'prefix' => 'tp6:cms:',
],
],
];
3. 安全防护
XSS防护:
// 在控制器中过滤输入
public function saveArticle()
{
$data = $this->request->only([
'category_id', 'title', 'content', 'author', 'status', 'is_top'
]);
// 过滤HTML内容,防止XSS
$data['content'] = clean($data['content'], 'html');
// 其他处理逻辑...
}
CSRF防护:
// 在表单中添加CSRF令牌
<form method="post" action="">
<?= token() ?>
<!-- 其他表单字段 -->
</form>
// 在验证器中验证CSRF令牌
protected $rule = [
// 其他规则...
'__token__' => 'token',
];
部署与上线
生产环境配置
// .env.production
APP_DEBUG = false
APP_TRACE = false
// 数据库配置
DATABASE_HOSTNAME = 127.0.0.1
DATABASE_DATABASE = production_db
DATABASE_USERNAME = production_user
DATABASE_PASSWORD = production_password
DATABASE_HOSTPORT = 3306
DATABASE_CHARSET = utf8mb4
// Redis配置
REDIS_HOST = 127.0.0.1
REDIS_PORT = 6379
REDIS_PASSWORD =
REDIS_SELECT = 0
优化自动加载
# 生成优化文件
php think optimize:autoload
# 生成路由缓存
php think optimize:route
# 生成配置缓存
php think optimize:config
定时任务配置
# 每天凌晨清理临时文件
0 0 * * * php /path/to/your/project/think clear:runtime
# 每小时备份数据库
0 * * * * php /path/to/your/project/think backup:database
总结
通过本教程,我们完整地构建了一个基于ThinkPHP 6.x的内容管理系统,涵盖了从环境搭建到部署上线的全过程。ThinkPHP 6.x提供了现代化的开发体验和强大的功能特性,使得开发企业级应用变得更加高效和愉快。
关键要点总结:
- 现代化架构:遵循PSR标准,采用中间件和依赖注入等现代PHP特性
- 模块化设计:清晰的分层架构,便于维护和扩展
- 安全可靠:内置多种安全机制,有效防护常见Web攻击
- 高性能:支持多种缓存机制,优化数据库查询
- 开发效率:丰富的命令行工具,自动化常见开发任务
ThinkPHP 6.x是一个功能全面、性能优异、易于上手的PHP框架,非常适合开发各种规模的Web应用程序。通过掌握ThinkPHP的核心概念和最佳实践,开发者可以快速构建出高质量、可维护的Web应用。