ThinkPHP 5.0.24 到 ThinkPHP 8.x 迁移学习指南
本指南帮助你从 ThinkPHP 5 快速过渡到 ThinkPHP 8,理解核心差异并掌握新特性。
目录
- 核心差异概览
- 环境要求变化
- 目录结构对比
- 命名空间变化
- 控制器层变化
- 模型层变化
- 路由系统变化
- 数据库操作变化
- 请求和响应
- 中间件系统
- 验证器变化
- 配置文件变化
- 依赖注入
- 服务容器
- 常用功能迁移对照表
- 学习路线图
核心差异概览
重大变化
| 特性 | 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 # 命令行工具
关键变化
- 应用目录改名 :
application/→app/ - 配置独立 :配置文件从
app/移到config/目录 - 路由独立 :路由定义从配置文件移到
route/目录 - 单应用模式:默认采用单应用模式,不再强制多模块
- 服务化 :新增
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();
}
}
关键变化
- 必须声明严格类型 :
declare(strict_types=1); - 必须声明返回类型 :
public function index(): string - 参数类型声明 :
public function hello(string $name): string - 基类变化 :继承
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 个后台控制器,建议:
-
按功能模块分组
app/admin/controller/
├── content/ # 内容管理相关
│ ├── Article.php
│ ├── Archives.php
│ └── Arctype.php
├── shop/ # 商城相关
│ ├── Product.php
│ ├── Order.php
│ └── Coupon.php
└── system/ # 系统管理
├── Config.php
└── Admin.php -
使用服务层
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+ 个模型,需要:
- 添加类型声明
- 修改查询方法:
get()→find(),all()→select() - 更新关联查询的类名引用
学习路线图
第一阶段:环境准备(1-2天)
- ✅ 安装 PHP 8.0+
- ✅ 安装 Composer
- ✅ 创建 TP8 测试项目
- ✅ 熟悉新的目录结构
第二阶段:核心概念(3-5天)
-
类型系统
- 学习 PHP 8 类型声明
- 理解严格类型模式
- 掌握联合类型、命名参数等新特性
-
依赖注入
- 理解依赖注入原理
- 掌握构造函数注入
- 学习服务容器使用
-
中间件系统
- 理解中间件概念
- 编写自定义中间件
- 掌握中间件注册方式
第三阶段:实战练习(5-7天)
-
创建简单的 CRUD 应用
- 用户管理模块
- 文章管理模块
- 实践模型、控制器、验证器
-
API 开发
- RESTful API 设计
- JWT 认证
- API 版本控制
-
高级特性
- 事件系统
- 队列任务
- 命令行工具
第四阶段:迁移实践(根据项目规模)
-
评估现有项目
- 统计控制器、模型数量
- 识别第三方依赖
- 评估自定义功能
-
制定迁移计划
- 优先迁移核心模块
- 逐步迁移业务模块
- 保持版本控制
-
测试验证
- 单元测试
- 功能测试
- 性能测试
快速上手示例
创建一个完整的用户管理模块
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
推荐学习资源
-
官方文档
- ThinkPHP 8.0 完全开发手册:https://doc.thinkphp.cn/v8_0/
- think-orm 文档:https://doc.thinkphp.cn/v8_0/orm.html
-
PHP 8 新特性
- PHP 8.0 新特性:https://www.php.net/releases/8.0/zh.php
- PHP 8.1 新特性:https://www.php.net/releases/8.1/zh.php
-
实战项目
- 从简单的博客系统开始
- 逐步增加复杂度
- 参考开源项目
总结
从 ThinkPHP 5 到 ThinkPHP 8 的主要变化:
- ✅ PHP 8 类型系统 - 强制类型声明,提高代码质量
- ✅ 依赖注入 - 更优雅的代码组织方式
- ✅ 中间件系统 - 替代行为钩子,更标准化
- ✅ 独立的 ORM - think-orm 可独立使用
- ✅ 配置分离 - 更清晰的配置管理
- ✅ 服务提供者 - 更好的服务注册机制
建议学习顺序:
- 先学习 PHP 8 新特性
- 创建简单的 TP8 项目练手
- 理解核心概念(依赖注入、中间件)
- 实战开发小项目
- 逐步迁移现有项目
祝你学习顺利!🚀