ThinkPHP 5.0.24 到 ThinkPHP 8.x 迁移学习指南

ThinkPHP 5.0.24 到 ThinkPHP 8.x 迁移学习指南

本指南帮助你从 ThinkPHP 5 快速过渡到 ThinkPHP 8,理解核心差异并掌握新特性。

目录

  1. 核心差异概览
  2. 环境要求变化
  3. 目录结构对比
  4. 命名空间变化
  5. 控制器层变化
  6. 模型层变化
  7. 路由系统变化
  8. 数据库操作变化
  9. 请求和响应
  10. 中间件系统
  11. 验证器变化
  12. 配置文件变化
  13. 依赖注入
  14. 服务容器
  15. 常用功能迁移对照表
  16. 学习路线图

核心差异概览

重大变化

特性 ThinkPHP 5.0.24 ThinkPHP 8.x
PHP 版本 PHP 5.4+ PHP 8.0+
命名空间 think\ think\ (保持)
ORM 内置 think-orm 3.0+ (独立包)
PSR 规范 部分支持 完全支持 PSR-2/PSR-4
类型声明 可选 强制使用 PHP 8 类型系统
依赖注入 基础支持 完善的容器和依赖注入
中间件 基础支持 完善的中间件系统
服务提供者 支持服务提供者模式
Composer 可选 必须使用

升级优势

性能提升 :利用 PHP 8 的 JIT 编译器,性能提升 20-30%

类型安全 :强类型声明减少运行时错误

现代化架构 :更符合现代 PHP 开发规范

更好的 IDE 支持 :类型提示带来更好的代码补全

独立的 ORM:think-orm 可以独立使用


环境要求变化

ThinkPHP 5.0.24

复制代码
PHP >= 5.4
MySQL >= 5.0
Apache/Nginx
可选:Redis、Memcache

ThinkPHP 8.x

复制代码
PHP >= 8.0 (必须)
推荐 PHP 8.1+
MySQL >= 5.7 或 MariaDB >= 10.2
Composer 2.0+
必须启用的 PHP 扩展:
  - PDO
  - MBString
  - JSON
  - OpenSSL

升级检查清单

bash 复制代码
# 检查 PHP 版本
php -v

# 检查已安装的扩展
php -m

# 检查 Composer 版本
composer --version

目录结构对比

ThinkPHP 5.0.24 目录结构

复制代码
project/
├── application/              # 应用目录
│   ├── admin/               # 后台模块
│   ├── home/                # 前台模块
│   ├── api/                 # API模块
│   ├── common/              # 公共模块
│   ├── config.php           # 应用配置
│   ├── database.php         # 数据库配置
│   ├── route.php            # 路由配置
│   ├── common.php           # 公共函数
│   └── tags.php             # 行为配置
├── public/                  # 入口目录
│   ├── index.php            # 入口文件
│   └── static/              # 静态资源
├── thinkphp/                # 框架核心目录
├── extend/                  # 扩展类库
├── runtime/                 # 运行时目录
├── vendor/                  # Composer依赖
└── composer.json

ThinkPHP 8.x 目录结构

复制代码
project/
├── app/                     # 应用目录(单应用模式)
│   ├── controller/          # 控制器目录
│   ├── model/               # 模型目录
│   ├── view/                # 视图目录
│   ├── middleware/          # 中间件目录
│   ├── validate/            # 验证器目录
│   ├── service/             # 服务层目录
│   ├── BaseController.php   # 控制器基类
│   ├── ExceptionHandle.php  # 异常处理
│   ├── Request.php          # 请求类
│   ├── AppService.php       # 应用服务
│   ├── common.php           # 公共函数
│   ├── event.php            # 事件配置
│   ├── middleware.php       # 中间件配置
│   ├── provider.php         # 服务提供者
│   └── service.php          # 服务配置
├── config/                  # 配置目录(独立)
│   ├── app.php              # 应用配置
│   ├── database.php         # 数据库配置
│   ├── cache.php            # 缓存配置
│   ├── route.php            # 路由配置
│   ├── middleware.php       # 中间件配置
│   └── ...
├── route/                   # 路由定义目录
│   └── app.php              # 应用路由
├── public/                  # 公共资源
│   ├── index.php            # 入口文件
│   └── static/              # 静态资源
├── runtime/                 # 运行时目录
├── extend/                  # 扩展目录
├── vendor/                  # Composer依赖
├── view/                    # 视图模板(可选)
├── composer.json
└── think                    # 命令行工具

关键变化

  1. 应用目录改名application/app/
  2. 配置独立 :配置文件从 app/ 移到 config/ 目录
  3. 路由独立 :路由定义从配置文件移到 route/ 目录
  4. 单应用模式:默认采用单应用模式,不再强制多模块
  5. 服务化 :新增 service/provider.php 等服务相关文件

命名空间变化

ThinkPHP 5.0.24

php 复制代码
<?php
namespace app\admin\controller;

use think\Controller;

class Index extends Controller
{
    public function index()
    {
        return $this->fetch();
    }
}

ThinkPHP 8.x

php 复制代码
<?php
declare(strict_types=1);

namespace app\controller;

use app\BaseController;

class Index extends BaseController
{
    public function index(): string
    {
        return $this->fetch();
    }
}

关键变化

  1. 必须声明严格类型declare(strict_types=1);
  2. 必须声明返回类型public function index(): string
  3. 参数类型声明public function hello(string $name): string
  4. 基类变化 :继承 app\BaseController 而不是 think\Controller

控制器层变化

1. 控制器基类

TP5 控制器
php 复制代码
<?php
namespace app\admin\controller;

use think\Controller;

class User extends Controller
{
    protected $beforeActionList = [
        'checkAuth' => ['except' => 'login']
    ];

    public function index()
    {
        $list = db('user')->select();
        $this->assign('list', $list);
        return $this->fetch();
    }

    protected function checkAuth()
    {
        // 权限检查
    }
}
TP8 控制器
php 复制代码
<?php
declare(strict_types=1);

namespace app\controller;

use app\BaseController;
use app\model\User as UserModel;

class User extends BaseController
{
    // 使用中间件替代前置操作
    protected array $middleware = [
        'auth' => ['except' => ['login']]
    ];

    public function index(): string
    {
        $list = UserModel::select();
        return $this->fetch('index', ['list' => $list]);
    }
}

2. 依赖注入

TP5 - 手动获取
php 复制代码
public function index()
{
    $request = request();
    $name = $request->param('name');

    $cache = cache();
    $data = $cache->get('key');
}
TP8 - 自动注入
php 复制代码
use think\Request;
use think\facade\Cache;

public function index(Request $request): string
{
    // 自动注入 Request 对象
    $name = $request->param('name');

    // 使用 Facade
    $data = Cache::get('key');

    return json(['name' => $name, 'data' => $data]);
}

3. 响应输出

TP5
php 复制代码
// 返回 JSON
return json(['code' => 0, 'msg' => 'success']);

// 返回视图
return $this->fetch('index');

// 重定向
return $this->redirect('user/index');
TP8
php 复制代码
// 返回 JSON(类型声明)
public function api(): \think\Response
{
    return json(['code' => 0, 'msg' => 'success']);
}

// 返回视图
public function index(): string
{
    return $this->fetch('index');
}

// 重定向
public function redirect(): \think\Response
{
    return redirect('/user/index');
}

模型层变化

1. 模型定义

TP5 模型
php 复制代码
<?php
namespace app\common\model;

use think\Model;

class User extends Model
{
    protected $table = 'user';
    protected $pk = 'id';

    // 自动时间戳
    protected $autoWriteTimestamp = true;
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';

    // 类型转换
    protected $type = [
        'status' => 'integer',
        'create_time' => 'timestamp'
    ];

    // 关联查询
    public function profile()
    {
        return $this->hasOne('UserProfile', 'user_id');
    }
}
TP8 模型
php 复制代码
<?php
declare(strict_types=1);

namespace app\model;

use think\Model;

class User extends Model
{
    protected string $table = 'user';
    protected string $pk = 'id';

    // 自动时间戳(类型声明)
    protected bool $autoWriteTimestamp = true;
    protected string $createTime = 'create_time';
    protected string $updateTime = 'update_time';

    // 类型转换(数组类型声明)
    protected array $type = [
        'status' => 'integer',
        'create_time' => 'timestamp',
        'extra' => 'json'  // JSON 字段支持
    ];

    // 关联查询(返回类型声明)
    public function profile(): \think\model\relation\HasOne
    {
        return $this->hasOne(UserProfile::class, 'user_id');
    }

    // 搜索器(新特性)
    public function searchNameAttr($query, $value): void
    {
        $query->where('name', 'like', '%' . $value . '%');
    }
}

2. 模型操作对比

TP5
php 复制代码
// 查询
$user = User::get(1);
$list = User::all([1, 2, 3]);
$users = User::where('status', 1)->select();

// 新增
$user = new User;
$user->name = 'test';
$user->save();

// 更新
$user = User::get(1);
$user->name = 'new name';
$user->save();

// 删除
User::destroy(1);
TP8
php 复制代码
// 查询(方法名变化)
$user = User::find(1);  // get() 改为 find()
$list = User::select([1, 2, 3]);  // all() 改为 select()
$users = User::where('status', 1)->select();

// 新增(支持类型提示)
$user = new User();
$user->name = 'test';
$user->save();

// 批量新增
User::insertAll([
    ['name' => 'user1'],
    ['name' => 'user2']
]);

// 更新
$user = User::find(1);
$user->name = 'new name';
$user->save();

// 删除
User::destroy(1);

// 软删除支持更好
$user->delete();  // 软删除
$user->force()->delete();  // 强制删除

路由系统变化

1. 路由定义位置

TP5

路由定义在 application/route.php

php 复制代码
<?php
use think\Route;

// 路由规则
Route::get('user/:id', 'user/read');
Route::post('user/save', 'user/save');
Route::rule('user/delete/:id', 'user/delete', 'DELETE');

// 路由分组
Route::group('admin', function () {
    Route::get('user/index', 'admin/user/index');
    Route::get('user/add', 'admin/user/add');
});
TP8

路由定义在 route/app.php(独立目录)

php 复制代码
<?php
use think\facade\Route;

// 路由规则(使用 Facade)
Route::get('user/:id', 'user/read');
Route::post('user/save', 'user/save');
Route::delete('user/delete/:id', 'user/delete');

// 路由分组
Route::group('admin', function () {
    Route::get('user/index', 'user/index');
    Route::get('user/add', 'user/add');
})->middleware(['auth']);  // 支持中间件

// RESTful 资源路由
Route::resource('article', 'Article');

2. 路由参数

TP5
php 复制代码
// 必选参数
Route::get('user/:id', 'user/read');

// 可选参数
Route::get('user/[:id]', 'user/read');

// 完全匹配
Route::get('user/:id$', 'user/read');
TP8
php 复制代码
// 必选参数(相同)
Route::get('user/<id>', 'user/read');

// 可选参数
Route::get('user/[<id>]', 'user/read');

// 参数类型约束
Route::get('user/<id:\d+>', 'user/read');  // 数字
Route::get('article/<name:\w+>', 'article/read');  // 字母数字下划线

// 参数验证
Route::get('user/<id>', 'user/read')
    ->pattern(['id' => '\d+']);

数据库操作变化

1. 查询构造器

TP5
php 复制代码
use think\Db;

// 基础查询
$list = Db::table('user')->where('status', 1)->select();

// 链式查询
$user = Db::name('user')
    ->where('id', 1)
    ->find();

// 聚合查询
$count = Db::name('user')->count();
$max = Db::name('user')->max('score');
TP8
php 复制代码
use think\facade\Db;

// 基础查询(使用 Facade)
$list = Db::table('user')->where('status', 1)->select();

// 链式查询(语法相同)
$user = Db::name('user')
    ->where('id', 1)
    ->find();

// 聚合查询
$count = Db::name('user')->count();
$max = Db::name('user')->max('score');

// 新增:更强大的查询方法
$list = Db::name('user')
    ->whereIn('id', [1, 2, 3])
    ->whereBetween('age', [18, 30])
    ->whereNull('deleted_at')
    ->select();

2. 事务处理

TP5
php 复制代码
Db::startTrans();
try {
    Db::name('user')->insert($data);
    Db::name('log')->insert($logData);
    Db::commit();
} catch (\Exception $e) {
    Db::rollback();
}
TP8
php 复制代码
use think\facade\Db;

// 方式1:手动事务(相同)
Db::startTrans();
try {
    Db::name('user')->insert($data);
    Db::name('log')->insert($logData);
    Db::commit();
} catch (\Exception $e) {
    Db::rollback();
}

// 方式2:自动事务(推荐)
Db::transaction(function () use ($data, $logData) {
    Db::name('user')->insert($data);
    Db::name('log')->insert($logData);
});

中间件系统

TP5 - 行为钩子

TP5 使用"行为"(Behavior)和"钩子"(Hook)机制

php 复制代码
// application/tags.php
return [
    'app_init' => [
        'app\\behavior\\CheckAuth',
    ],
];

// 行为类
namespace app\behavior;

class CheckAuth
{
    public function run()
    {
        // 权限检查逻辑
    }
}

TP8 - 中间件系统

TP8 采用标准的中间件模式

1. 定义中间件
php 复制代码
<?php
declare(strict_types=1);

namespace app\middleware;

class Auth
{
    public function handle($request, \Closure $next)
    {
        // 前置中间件逻辑
        if (!session('user_id')) {
            return redirect('/login');
        }

        $response = $next($request);

        // 后置中间件逻辑
        return $response;
    }
}
2. 注册中间件

全局中间件 - app/middleware.php

php 复制代码
<?php
return [
    // 全局中间件
    \app\middleware\Auth::class,
];

路由中间件 - route/app.php

php 复制代码
Route::group('admin', function () {
    Route::get('user/index', 'user/index');
})->middleware([\app\middleware\Auth::class]);

控制器中间件

php 复制代码
class User extends BaseController
{
    protected array $middleware = [
        'auth' => ['except' => ['login', 'register']]
    ];
}

ThinkPHP 5 到 ThinkPHP 8 迁移指南 - 补充篇

本文档是《tp5~tp8的差异.md》的补充内容

请求和响应

1. 请求对象

TP5
php 复制代码
// 获取请求参数
$name = input('name');
$id = input('id/d');  // 强制转换为整数
$data = input('post.');  // 获取所有POST数据

// 或使用 Request 对象
$request = request();
$name = $request->param('name');
$method = $request->method();
TP8
php 复制代码
use think\Request;

// 依赖注入(推荐)
public function index(Request $request): string
{
    $name = $request->param('name');
    $id = $request->param('id', 0, 'intval');
    $data = $request->post();

    // 获取请求方法
    $method = $request->method();

    // 判断请求类型
    if ($request->isPost()) {
        // POST 请求
    }

    return 'success';
}

验证器变化

TP5 验证器

php 复制代码
<?php
namespace app\common\validate;

use think\Validate;

class User extends Validate
{
    protected $rule = [
        'name'  => 'require|max:25',
        'email' => 'email',
        'age'   => 'number|between:1,120',
    ];

    protected $message = [
        'name.require' => '名称必须',
        'email'        => '邮箱格式错误',
    ];
}

// 使用验证器
$validate = new \app\common\validate\User;
if (!$validate->check($data)) {
    return $validate->getError();
}

TP8 验证器

php 复制代码
<?php
declare(strict_types=1);

namespace app\validate;

use think\Validate;

class User extends Validate
{
    protected array $rule = [
        'name'  => 'require|max:25',
        'email' => 'email',
        'age'   => 'number|between:1,120',
    ];

    protected array $message = [
        'name.require' => '名称必须',
        'email'        => '邮箱格式错误',
    ];

    // 场景定义
    protected array $scene = [
        'add'  => ['name', 'email'],
        'edit' => ['name'],
    ];
}

// 使用验证器(在控制器中)
public function save(Request $request): \think\Response
{
    $data = $request->post();

    // 方式1:手动验证
    $validate = new \app\validate\User;
    if (!$validate->scene('add')->check($data)) {
        return json(['code' => 1, 'msg' => $validate->getError()]);
    }

    // 方式2:使用 validate 方法(推荐)
    try {
        $this->validate($data, \app\validate\User::class);
    } catch (\think\exception\ValidateException $e) {
        return json(['code' => 1, 'msg' => $e->getError()]);
    }

    return json(['code' => 0, 'msg' => 'success']);
}

配置文件变化

TP5 配置

配置文件在 application/config.php

php 复制代码
<?php
return [
    'app_debug' => true,
    'app_trace' => false,
    'default_return_type' => 'html',
    'default_ajax_return' => 'json',
    'url_route_on' => true,
    'url_route_must' => false,
];

TP8 配置

配置文件在 config/ 目录下,按功能分离

config/app.php

php 复制代码
<?php
return [
    'debug' => env('app.debug', false),
    'trace' => env('app.trace', false),
    'default_timezone' => 'Asia/Shanghai',
    'exception_tmpl' => app()->getThinkPath() . 'tpl/think_exception.tpl',
];

config/route.php

php 复制代码
<?php
return [
    'default_controller' => 'Index',
    'default_action' => 'index',
    'url_html_suffix' => 'html',
];

使用环境变量(.env)

env 复制代码
APP_DEBUG = true
APP_TRACE = false

[DATABASE]
TYPE = mysql
HOSTNAME = 127.0.0.1
DATABASE = test
USERNAME = root
PASSWORD =
HOSTPORT = 3306

依赖注入和服务容器

TP5 - 基础依赖注入

php 复制代码
// 控制器方法注入
public function index(Request $request)
{
    // 自动注入 Request 对象
}

// 手动获取服务
$cache = app('cache');

TP8 - 完善的依赖注入

php 复制代码
<?php
declare(strict_types=1);

namespace app\controller;

use app\service\UserService;
use think\Request;

class User extends BaseController
{
    // 构造函数注入
    public function __construct(
        protected UserService $userService
    ) {}

    // 方法注入
    public function index(Request $request): string
    {
        $list = $this->userService->getList();
        return json($list);
    }
}

定义服务类

php 复制代码
<?php
declare(strict_types=1);

namespace app\service;

use app\model\User;

class UserService
{
    public function getList(): array
    {
        return User::select()->toArray();
    }

    public function create(array $data): bool
    {
        $user = new User();
        return $user->save($data);
    }
}

服务提供者(app/provider.php)

php 复制代码
<?php
return [
    \app\AppService::class,
];

常用功能迁移对照表

功能 ThinkPHP 5 ThinkPHP 8
获取配置 config('app.debug') config('app.debug') ✅ 相同
缓存操作 cache('key', 'value') Cache::set('key', 'value')
Session session('user_id') Session::get('user_id')
Cookie cookie('name') Cookie::get('name')
日志记录 \think\Log::record('msg') Log::info('msg')
模型查询 User::get(1) User::find(1) ⚠️ 方法名变化
模型查询 User::all() User::select() ⚠️ 方法名变化
数据库查询 Db::name('user') Db::name('user') ✅ 相同
助手函数 input('name') request()->param('name')
URL生成 url('user/index') url('user/index') ✅ 相同
重定向 $this->redirect() redirect()
JSON输出 json($data) json($data) ✅ 相同
视图渲染 $this->fetch() $this->fetch() ✅ 相同

易优CMS 迁移到 TP8 的关键点

基于你的 TP5 项目(易优CMS),以下是迁移到 TP8 的关键考虑点:

1. 多模块架构调整

TP5 结构

复制代码
application/
├── admin/      # 后台模块
├── home/       # 前台模块
├── api/        # API模块
└── user/       # 用户模块

TP8 建议结构

复制代码
app/
├── admin/
│   ├── controller/
│   ├── model/
│   └── middleware/
├── home/
│   ├── controller/
│   └── view/
├── api/
│   └── controller/
└── common/
    ├── model/
    ├── service/
    └── validate/

2. 控制器数量庞大的处理

你的项目有 71 个后台控制器,建议:

  1. 按功能模块分组

    app/admin/controller/
    ├── content/ # 内容管理相关
    │ ├── Article.php
    │ ├── Archives.php
    │ └── Arctype.php
    ├── shop/ # 商城相关
    │ ├── Product.php
    │ ├── Order.php
    │ └── Coupon.php
    └── system/ # 系统管理
    ├── Config.php
    └── Admin.php

  2. 使用服务层

php 复制代码
// 将复杂业务逻辑移到服务层
app/service/
├── ArticleService.php
├── ProductService.php
└── OrderService.php

3. 公共函数迁移

你的项目有大量公共函数(311KB),建议:

TP5

php 复制代码
// application/common.php
function get_arctype_info($id) {
    // ...
}

TP8

php 复制代码
// app/common.php(保持相同位置)
function get_arctype_info(int $id): array {
    // 添加类型声明
}

// 或者改为服务类
namespace app\service;

class ArctypeService {
    public function getInfo(int $id): array {
        // ...
    }
}

4. 模板系统

模板语法基本兼容,但需要注意:

TP5

html 复制代码
{$user.name}
{volist name="list" id="vo"}
    {$vo.title}
{/volist}

TP8

html 复制代码
{$user.name}  <!-- 相同 -->
{volist name="list" id="vo"}
    {$vo.title}
{/volist}

5. 数据库迁移

你的项目有 60+ 个模型,需要:

  1. 添加类型声明
  2. 修改查询方法:get()find()all()select()
  3. 更新关联查询的类名引用

学习路线图

第一阶段:环境准备(1-2天)

  1. ✅ 安装 PHP 8.0+
  2. ✅ 安装 Composer
  3. ✅ 创建 TP8 测试项目
  4. ✅ 熟悉新的目录结构

第二阶段:核心概念(3-5天)

  1. 类型系统

    • 学习 PHP 8 类型声明
    • 理解严格类型模式
    • 掌握联合类型、命名参数等新特性
  2. 依赖注入

    • 理解依赖注入原理
    • 掌握构造函数注入
    • 学习服务容器使用
  3. 中间件系统

    • 理解中间件概念
    • 编写自定义中间件
    • 掌握中间件注册方式

第三阶段:实战练习(5-7天)

  1. 创建简单的 CRUD 应用

    • 用户管理模块
    • 文章管理模块
    • 实践模型、控制器、验证器
  2. API 开发

    • RESTful API 设计
    • JWT 认证
    • API 版本控制
  3. 高级特性

    • 事件系统
    • 队列任务
    • 命令行工具

第四阶段:迁移实践(根据项目规模)

  1. 评估现有项目

    • 统计控制器、模型数量
    • 识别第三方依赖
    • 评估自定义功能
  2. 制定迁移计划

    • 优先迁移核心模块
    • 逐步迁移业务模块
    • 保持版本控制
  3. 测试验证

    • 单元测试
    • 功能测试
    • 性能测试

快速上手示例

创建一个完整的用户管理模块

1. 创建数据表
sql 复制代码
CREATE TABLE `user` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(50) NOT NULL,
  `email` varchar(100) NOT NULL,
  `status` tinyint(1) DEFAULT '1',
  `create_time` datetime DEFAULT NULL,
  `update_time` datetime DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;
2. 创建模型
php 复制代码
<?php
declare(strict_types=1);

namespace app\model;

use think\Model;

class User extends Model
{
    protected array $type = [
        'status' => 'integer',
        'create_time' => 'datetime',
        'update_time' => 'datetime',
    ];

    protected bool $autoWriteTimestamp = true;
}
3. 创建验证器
php 复制代码
<?php
declare(strict_types=1);

namespace app\validate;

use think\Validate;

class User extends Validate
{
    protected array $rule = [
        'name'  => 'require|max:50',
        'email' => 'require|email|unique:user',
    ];

    protected array $message = [
        'name.require'  => '用户名必须填写',
        'email.require' => '邮箱必须填写',
        'email.email'   => '邮箱格式不正确',
        'email.unique'  => '邮箱已存在',
    ];
}
4. 创建控制器
php 复制代码
<?php
declare(strict_types=1);

namespace app\controller;

use app\BaseController;
use app\model\User;
use think\Request;
use think\Response;

class UserController extends BaseController
{
    // 列表
    public function index(): string
    {
        $list = User::select();
        return json(['code' => 0, 'data' => $list]);
    }

    // 详情
    public function read(int $id): Response
    {
        $user = User::find($id);
        if (!$user) {
            return json(['code' => 1, 'msg' => '用户不存在']);
        }
        return json(['code' => 0, 'data' => $user]);
    }

    // 新增
    public function save(Request $request): Response
    {
        $data = $request->post();

        try {
            $this->validate($data, \app\validate\User::class);
        } catch (\think\exception\ValidateException $e) {
            return json(['code' => 1, 'msg' => $e->getError()]);
        }

        $user = new User();
        $user->save($data);

        return json(['code' => 0, 'msg' => '添加成功']);
    }

    // 更新
    public function update(Request $request, int $id): Response
    {
        $user = User::find($id);
        if (!$user) {
            return json(['code' => 1, 'msg' => '用户不存在']);
        }

        $data = $request->put();
        $user->save($data);

        return json(['code' => 0, 'msg' => '更新成功']);
    }

    // 删除
    public function delete(int $id): Response
    {
        $user = User::find($id);
        if (!$user) {
            return json(['code' => 1, 'msg' => '用户不存在']);
        }

        $user->delete();
        return json(['code' => 0, 'msg' => '删除成功']);
    }
}
5. 配置路由
php 复制代码
<?php
use think\facade\Route;

// RESTful 资源路由
Route::resource('user', 'UserController');

// 等同于:
// GET    /user          -> index
// GET    /user/:id      -> read
// POST   /user          -> save
// PUT    /user/:id      -> update
// DELETE /user/:id      -> delete

推荐学习资源

  1. 官方文档

  2. PHP 8 新特性

  3. 实战项目

    • 从简单的博客系统开始
    • 逐步增加复杂度
    • 参考开源项目

总结

从 ThinkPHP 5 到 ThinkPHP 8 的主要变化:

  1. PHP 8 类型系统 - 强制类型声明,提高代码质量
  2. 依赖注入 - 更优雅的代码组织方式
  3. 中间件系统 - 替代行为钩子,更标准化
  4. 独立的 ORM - think-orm 可独立使用
  5. 配置分离 - 更清晰的配置管理
  6. 服务提供者 - 更好的服务注册机制

建议学习顺序

  1. 先学习 PHP 8 新特性
  2. 创建简单的 TP8 项目练手
  3. 理解核心概念(依赖注入、中间件)
  4. 实战开发小项目
  5. 逐步迁移现有项目

祝你学习顺利!🚀

相关推荐
m0_738120723 小时前
渗透测试——靶机DC-6详细横向过程(Wordpress渗透)
服务器·网络·python·web安全·ssh·php
傻啦嘿哟4 小时前
实战:用GraphQL接口高效采集数据
开发语言·驱动开发·php
BingoGo4 小时前
CatchAdmin 2025 年终总结 模块化架构的进化之路
后端·开源·php
qq_117179074 小时前
海康威视球机萤石云不在线问题解决方案
开发语言·智能路由器·php
FreeBuf_5 小时前
欧洲航天局确认外部服务器遭入侵
服务器·安全·php
catchadmin5 小时前
2025 年的 PHP:没大改,却更好用了
php
BingoGo5 小时前
2026 年 PHP 开发者进阶 快速高效开发学习习惯
后端·php
chian-ocean5 小时前
网络世界的“搬运工”:深入理解数据链路层
开发语言·网络·php
软件供应链安全指南5 小时前
悬镜安全:风险情报驱动的数字供应链安全治理实践
开发语言·安全·php