ThinkPHP
ThinkPHP 是一款由中国开发者刘晨(花名:流年)创建的国产 PHP 框架,是国内使用最广泛的 PHP 框架之一。它以"为开发而设计"为理念,提供了简洁优雅的 API、强大的 ORM、多应用支持和完善的中文文档。ThinkPHP 特别适合中小型项目和快速开发场景,在国内 PHP 社区拥有庞大的用户群。本节将全面介绍 ThinkPHP 的核心概念和使用方法。
基础概念
ThinkPHP 的特点
| 特性 | 说明 |
|---|---|
| 中文友好 | 完善的中文文档和社区 |
| 多应用模式 | 支持单应用和多应用架构 |
| 内置 ORM | 强大的数据库查询构造器 |
| 快速开发 | 约定优于配置,减少样板代码 |
| 验证器 | 内置强大的数据验证机制 |
| 中间件 | HTTP 中间件支持 |
| 缓存驱动 | 支持多种缓存后端 |
| 模板引擎 | 内置模板引擎,支持标签 |
版本信息
| ThinkPHP | PHP 最低版本 | 支持状态 |
|---|---|---|
| ThinkPHP 8.0 | PHP 8.0 | 当前版本 |
| ThinkPHP 6.x | PHP 7.2.5 | 维护中 |
| ThinkPHP 5.1 | PHP 5.6 | 已结束支持 |
详细说明
项目创建
bash
# 使用 Composer 创建项目
composer create-project topthink/think myapp
# 或使用 ThinkPHP 安装器
composer global require topthink/installer
think new myapp目录结构
thinkphp-project/
├── app/ # 应用目录
│ ├── controller/ # 控制器
│ ├── model/ # 模型
│ ├── validate/ # 验证器
│ ├── middleware/ # 中间件
│ └── service/ # 服务层
├── config/ # 配置文件
├── public/ # Web 根目录
│ └── index.php # 入口文件
├── route/ # 路由定义
├── runtime/ # 运行时缓存
├── vendor/ # Composer 依赖
├── extend/ # 扩展类库
└── composer.json路由定义
php
<?php
// route/app.php
use think\facade\Route;
// 基本路由
Route::get('/', fn() => 'Hello World');
Route::get('hello/:name', 'IndexController/hello');
// 控制器路由
Route::get('users', 'UserController/index');
Route::get('users/:id', 'UserController/read');
// 资源路由
Route::resource('posts', 'PostController');
// 路由分组
Route::group(function () {
Route::get('profile', 'UserController/profile');
Route::post('update', 'UserController/update');
})->middleware('auth');
// RESTful API 路由
Route::group('api')->prefix('v1')->middleware('auth')->allowCrossDomain([
'users' => ['index' => 'GET', 'save' => 'POST'],
]);控制器
php
<?php
declare(strict_types=1);
namespace app\controller;
use app\model\User;
use think\exception\ValidateException;
use think\facade\Db;
use think\Request;
use think\Response;
class UserController
{
// 列表
public function index(): Response
{
$users = User::where('status', 1)
->order('create_time', 'desc')
->paginate(20);
return json(['code' => 200, 'data' => $users]);
}
// 详情
public function read(int $id): Response
{
$user = User::findOrFail($id);
return json(['code' => 200, 'data' => $user]);
}
// 创建
public function save(Request $request): Response
{
try {
$data = $request->only(['name', 'email', 'password']);
validate($data, [
'name' => 'require|max:50',
'email' => 'require|email|unique:user',
'password' => 'require|min:6',
]);
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => password_hash($data['password'], PASSWORD_DEFAULT),
]);
return json(['code' => 201, 'data' => $user]);
} catch (ValidateException $e) {
return json(['code' => 422, 'message' => $e->getError()]);
}
}
// 更新
public function update(Request $request, int $id): Response
{
$user = User::findOrFail($id);
$user->save($request->only(['name', 'email']));
return json(['code' => 200, 'data' => $user]);
}
// 删除
public function delete(int $id): Response
{
User::destroy($id);
return json(['code' => 204]);
}
}模型
php
<?php
declare(strict_types=1);
namespace app\model;
use think\Model;
class User extends Model
{
// 表名(默认与类名对应)
protected $name = 'user';
// 自动写入时间戳
protected $autoWriteTimestamp = true;
// 只读字段
protected readonly string $email;
// 隐藏字段
protected $hidden = ['password'];
// 类型转换
protected $type = [
'status' => 'integer',
'is_admin' => 'boolean',
'create_time' => 'datetime',
];
// 搜索器(条件查询封装)
public function searchNameAttr($query, $value, $data)
{
$query->where('name', 'like', '%' . $value . '%');
}
// 修改器
public function setPasswordAttr(string $value): string
{
return password_hash($value, PASSWORD_DEFAULT);
}
// 获取器
public function getStatusTextAttr($value, $data): string
{
return $data['status'] ? '启用' : '禁用';
}
// 关联关系:一对多
public function posts(): \think\model\relation\HasMany
{
return $this->hasMany(Post::class);
}
// 关联关系:属于
public function department(): \think\model\relation\BelongsTo
{
return $this->belongsTo(Department::class);
}
// 全局作用域
public function scopeActive($query)
{
$query->where('status', 1);
}
}数据库查询
php
<?php
declare(strict_types=1);
use think\facade\Db;
// 查询构造器
$users = Db::name('user')
->where('status', 1)
->where('name', 'like', '%张%')
->order('id', 'desc')
->limit(10)
->select()
->toArray();
// 事务
Db::transaction(function () {
Db::name('user')->where('id', 1)->dec('balance', 100);
Db::name('order')->insert([
'user_id' => 1,
'amount' => 100,
]);
});
// 分页
$users = Db::name('user')->paginate(20, false, [
'query' => request()->param(),
]);中间件
php
<?php
declare(strict_types=1);
namespace app\middleware;
use think\Request;
use think\Response;
class AuthMiddleware
{
public function handle(Request $request, \Closure $next): Response
{
$token = $request->header('Authorization');
if (!$token || !$this->validateToken($token)) {
return json(['code' => 401, 'message' => '未授权'], 401);
}
return $next($request);
}
private function validateToken(string $token): bool
{
// 验证 token 逻辑
return true;
}
}验证器
php
<?php
declare(strict_types=1);
namespace app\validate;
use think\Validate;
class UserValidate extends Validate
{
protected $rule = [
'name' => 'require|max:50|chsAlpha',
'email' => 'require|email|unique:user',
'password' => 'require|min:6|confirm',
'phone' => 'require|mobile',
'age' => 'number|between:1,150',
];
protected $message = [
'name.require' => '用户名不能为空',
'name.max' => '用户名最多50个字符',
'email.require' => '邮箱不能为空',
'email.email' => '邮箱格式不正确',
'email.unique' => '邮箱已存在',
'password.min' => '密码至少6个字符',
'password.confirm' => '两次密码不一致',
];
protected $scene = [
'create' => ['name', 'email', 'password'],
'update' => ['name', 'email'],
'login' => ['email', 'password'],
];
}php
<?php
// 使用验证器
$validate = new \app\validate\UserValidate();
$result = $validate->scene('create')->batch()->check($data);
if (!$result) {
return json(['code' => 422, 'message' => $validate->getError()]);
}缓存系统
php
<?php
use think\facade\Cache;
// 基本缓存操作
Cache::set('key', 'value', 3600);
$value = Cache::get('key', 'default');
Cache::delete('key');
Cache::has('key');
Cache::inc('counter');
Cache::dec('counter', 5);
// 标签缓存
Cache::tag('user')->set('profile', $data);
Cache::tag('user')->clear();实战示例
场景一:API 认证流程
php
<?php
declare(strict_types=1);
namespace app\controller;
use app\model\User;
use app\service\TokenService;
use think\facade\Cache;
use think\Request;
use think\Response;
class AuthController
{
public function login(Request $request): Response
{
$data = $request->only(['email', 'password']);
$user = User::where('email', $data['email'])->find();
if (!$user || !password_verify($data['password'], $user->password)) {
return json(['code' => 401, 'message' => '邮箱或密码错误']);
}
$token = TokenService::generate($user);
Cache::set("token:{$token}", $user->id, 7200);
return json([
'code' => 200,
'data' => [
'token' => $token,
'user' => $user->hidden(['password']),
],
]);
}
}注意事项
1. 版本差异
ThinkPHP 5.x 和 6.x/8.x 之间存在较大差异,升级时需要注意兼容性。ThinkPHP 8.x 支持 PHP 8.0+,推荐新项目使用。
2. 多应用模式
bash
# 创建多应用项目
composer create-project topthink/think myapp
cd myapp
# 安装多应用扩展
composer require topthink/think-multi-app
# 创建新应用
php think build app\admin
php think build app/api最佳实践
1. 使用服务层
php
<?php
declare(strict_types=1);
namespace app\service;
use app\model\User;
class UserService
{
public function createUser(array $data): User
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => password_hash($data['password'], PASSWORD_DEFAULT),
]);
}
public function getUserById(int $id): ?User
{
return User::where('status', 1)->find($id);
}
}ThinkPHP vs Laravel
- ThinkPHP:中文文档完善、国内社区活跃、上手简单
- Laravel:全球社区更大、生态系统更丰富、代码更优雅
- 根据项目需求和团队背景选择合适的框架
下一节
继续学习:Yii 框架 — 了解另一个优秀的 PHP 框架。