Skip to content

ThinkPHP

ThinkPHP 是一款由中国开发者刘晨(花名:流年)创建的国产 PHP 框架,是国内使用最广泛的 PHP 框架之一。它以"为开发而设计"为理念,提供了简洁优雅的 API、强大的 ORM、多应用支持和完善的中文文档。ThinkPHP 特别适合中小型项目和快速开发场景,在国内 PHP 社区拥有庞大的用户群。本节将全面介绍 ThinkPHP 的核心概念和使用方法。

前置知识

阅读本节前,建议先了解:

基础概念

ThinkPHP 的特点

特性说明
中文友好完善的中文文档和社区
多应用模式支持单应用和多应用架构
内置 ORM强大的数据库查询构造器
快速开发约定优于配置,减少样板代码
验证器内置强大的数据验证机制
中间件HTTP 中间件支持
缓存驱动支持多种缓存后端
模板引擎内置模板引擎,支持标签

版本信息

ThinkPHPPHP 最低版本支持状态
ThinkPHP 8.0PHP 8.0当前版本
ThinkPHP 6.xPHP 7.2.5维护中
ThinkPHP 5.1PHP 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 框架。

参考链接