ThinkPHP5.0.24 升级 ThinkPHP8.1 实战指南

yvsm4个月前PHP11960

从 ThinkPHP5.0.24 升级至 ThinkPHP8.1,虽无 TP3 升级的跨度大,但核心差异体现在命名空间规范、ORM 语法、路由机制、验证体系及 PHP 版本兼容(TP8 要求 PHP8.0+)。本文覆盖控制器、模型、路由、验证、数据库操作等核心模块,通过“TP5.0.24 旧代码 vs TP8.1 新代码”的对比形式,直观呈现升级要点,助力开发者高效完成升级。

前置说明:升级前需完成 3 件事① 备份代码与数据库,创建独立升级分支;② 部署 PHP8.0+ 环境(推荐 PHP8.1),升级 Composer 至 2.x 版本;③ 新建 TP8.1 项目(composer create-project topthink/think tp81-project),后续将 TP5.0.24 核心代码迁移至新项目并适配修改。

一、目录结构与入口文件修改

TP5.0.24 与 TP8.1 目录结构有一定延续性,但核心目录命名、入口文件位置仍有调整,需先完成基础目录迁移与入口文件适配。

1. 目录迁移核心规则

TP5.0.24 目录/文件TP8.1 对应目录/文件关键说明
application/app/应用目录重命名为 app/,模块(如 index、admin)直接迁移,目录名保持小写
application/config.phpconfig/app.php + config/database.php配置文件拆分,按 TP8.1 规范分类存放(数据库配置独立为 database.php)
public/index.php(根目录)public/index.php入口文件位置不变,但内部逻辑更新,直接替换为 TP8.1 标准入口文件
thinkphp/vendor/topthink/think-framework/TP8.1 采用 Composer 管理核心框架,不再保留独立 thinkphp 目录

2. 入口文件代码修改示例

TP5.0.24 public/index.php(旧代码):

<?php
// [ 应用入口文件 ]
namespace think;

// 加载基础文件
require __DIR__ . '/../thinkphp/base.php';

// 执行应用并响应
Container::get('app')->run()->send();

TP8.1 public/index.php(新代码):

<?php
// [ 应用入口文件 ]
namespace think;

// 加载基础文件
require __DIR__ . '/../vendor/autoload.php';

// 执行应用并响应
$http = (new App())->http;

$response = $http->run();

$response->send();

$http->end($response);

二、控制器代码修改:命名空间与请求适配

TP5.0.24 控制器已支持命名空间,但 TP8.1 对命名空间规范、请求参数获取、响应方式有更严格的要求,同时废弃部分快捷方法。

核心修改示例:基础控制器

TP5.0.24 application/index/controller/Index.php(旧代码):

<?php
namespace app\index\controller;

class Index 
{
    // 首页方法
    public function index() 
    {
        // 接收参数
        $id = input('get.id', 0, 'intval');
        // 渲染模板
        return $this->fetch('index', ['id' => $id]);
    }

    // 跳转响应
    public function redirectDemo()
    {
        // 页面跳转
        $this->success('操作成功', 'index/index');
        // 或
        $this->error('操作失败', 'index/index');
    }
}

TP8.1 app/controller/Index.php(新代码):

<?php
namespace app\controller;
use think\Controller;
use think\facade\Request; // 引入请求门面
use think\facade\Redirect; // 引入重定向门面

class Index extends Controller 
{
    // 首页方法(支持依赖注入)
    public function index(Request $request) 
    {
        // 接收参数(input()函数仍可用,但推荐门面方式)
        $id = $request->get('id', 0, 'intval');
        // 渲染模板(模板目录仍为 view/,路径规则不变)
        return $this->fetch('index', ['id' => $id]);
    }

    // 跳转响应(废弃success/error快捷方法)
    public function redirectDemo()
    {
        // 成功跳转(替代success)
        return Redirect::to('/index/index')->with('msg', '操作成功');
        // 失败提示(替代error)
        // return Redirect::to('/index/index')->with('error', '操作失败');
    }
}

关键修改点:① 推荐继承 think\Controller 以使用模板渲染等方法;② 请求参数获取推荐使用 Request 门面替代 input()(input() 仍兼容但不推荐);③ 废弃 success()/error() 快捷方法,改用 Redirect 门面实现跳转。

三、模型代码修改:ORM 语法与特性升级

TP5.0.24 与 TP8.1 均基于 think-orm,但 TP8.1 升级至 think-orm 3.0+,模型的时间戳、软删除、关联查询语法有细节调整,且强化了类型提示。

1. 基础模型修改示例

TP5.0.24 application/index/model/User.php(旧代码):

<?php
namespace app\index\model;
use think\Model;
use traits\model\SoftDelete;

class User extends Model 
{
    // 软删除
    use SoftDelete;
    protected $deleteTime = 'delete_time';
    protected $defaultSoftDelete = 0;

    // 时间戳字段
    protected $autoWriteTimestamp = true;
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';

    // 字段类型转换
    protected $type = [
        'status' => 'integer',
        'create_time' => 'datetime',
    ];
}

TP8.1 app/model/User.php(新代码):

<?php
namespace app\model;
use think\Model;
use think\model\concern\SoftDelete; // 软删除Trait路径变更

class User extends Model 
{
    // 软删除(Trait命名空间调整)
    use SoftDelete;
    protected $deleteTime = 'delete_time';
    protected $defaultSoftDelete = 0;

    // 时间戳(无需手动开启autoWriteTimestamp,默认开启)
    protected $createTime = 'create_time';
    protected $updateTime = 'update_time';

    // 字段类型转换(语法不变,推荐增加类型提示)
    protected $type = [
        'status' => 'int', // 简化类型标识
        'create_time' => 'datetime',
    ];
}

2. 关联查询修改示例

TP5.0.24 模型关联(旧代码):

// User模型中定义关联
public function order() 
{
    // 一对一关联
    return $this->hasOne('Order', 'user_id', 'id');
}

// 控制器中调用
$user = \app\index\model\User::get(1);
$orderInfo = $user->order;

TP8.1 模型关联(新代码):

// User模型中定义关联
use app\model\Order; // 显式引入关联模型

public function order() 
{
    // 一对一关联(推荐使用类名常量)
    return $this->hasOne(Order::class, 'user_id', 'id');
}

// 控制器中调用(推荐预加载提升性能)
use app\model\User;

$user = User::with('order')->find(1);
$orderInfo = $user->order;

四、路由配置修改:从混合定义到显式声明

TP5.0.24 支持路由配置文件 + 注解路由,TP8.1 强化了路由门面的使用,废弃部分旧语法,同时新增路由分组、中间件绑定等高级特性。

核心修改示例

TP5.0.24 route/route.php(旧代码):

<?php
use think\Route;

// 基础路由
Route::get('user/:id', 'index/user/info');

// 带正则约束的路由
Route::get('article/:id', 'index/article/detail')
    ->pattern(['id' => '\d+']);

// 路由分组
Route::group('admin', function() {
    Route::get('login', 'admin/index/login');
})->middleware('Auth');

TP8.1 config/route.php(新代码):

<?php
use think\facade\Route;

// 基础路由(命名空间简化)
Route::get('user/:id', 'User/info');

// 带正则约束的路由(pattern改为rule)
Route::get('article/:id', 'Article/detail')
    ->rule(['id' => '\d+']);

// 路由分组(语法优化,支持更多特性)
Route::group('admin', function() {
    Route::get('login', 'Admin/login');
    Route::get('dashboard', 'Admin/dashboard');
})
->middleware('Auth') // 中间件绑定
->rule(['id' => '\d+']) // 分组通用正则
->when(['id' => '>0'], 'ID必须大于0'); // 新增参数验证

关键修改点:① 路由配置文件路径从 route/route.php 迁移至 config/route.php;② pattern() 方法替换为 rule();③ 控制器路径简化(无需写 index/ 前缀,默认从 app/controller 读取);④ 新增路由参数验证、分组通用规则等特性。

五、验证逻辑修改:验证器升级与语法优化

TP5.0.24 已支持独立验证器,但 TP8.1 对验证器的命名空间、规则定义、场景使用有细节调整,同时新增更多验证规则。

核心修改示例

TP5.0.24 application/index/validate/User.php(旧代码):

<?php
namespace app\index\validate;
use think\Validate;

class User extends Validate
{
    // 验证规则
    protected $rule = [
        'username' => 'require|length:5,20',
        'password' => 'require|length:6,20',
        'email'    => 'require|email',
    ];

    // 错误提示
    protected $message = [
        'username.require' => '用户名不能为空',
        'password.require' => '密码不能为空',
        'email.email'      => '邮箱格式错误',
    ];

    // 场景验证
    protected $scene = [
        'add'  => ['username', 'password', 'email'],
        'edit' => ['username'],
    ];
}

TP8.1 app/validate/User.php(新代码):

<?php
namespace app\validate;
use think\Validate;

class User extends Validate
{
    // 验证规则(新增更多内置规则)
    protected $rule = [
        'username' => 'require|chsAlphaNum|length:5,20', // 新增汉字字母数字验证
        'password' => 'require|length:6,20|alphaNum', // 新增字母数字验证
        'email'    => 'require|email|unique:user', // 新增唯一验证
    ];

    // 错误提示(支持更灵活的自定义)
    protected $message = [
        'username.require'    => '用户名不能为空',
        'username.chsAlphaNum'=> '用户名只能包含汉字、字母和数字',
        'password.alphaNum'   => '密码只能包含字母和数字',
        'email.unique'        => '该邮箱已被注册',
    ];

    // 场景验证(语法不变,支持动态场景)
    protected $scene = [
        'add'  => ['username', 'password', 'email'],
        'edit' => ['username'],
    ];
}

控制器调用示例(TP8.1):

<?php
namespace app\controller;
use app\validate\User as UserValidate;
use think\facade\Request;

class User
{
    public function add()
    {
        if (Request::isPost()) {
            $data = Request::post();
            // 实例化验证器
            $validate = new UserValidate();
            // 场景验证
            if (!$validate->scene('add')->check($data)) {
                return $this->error($validate->getError());
            }
            // 数据入库
            // ...
        }
    }
}

六、数据库操作修改:查询语法与兼容性调整

TP5.0.24 与 TP8.1 的数据库操作语法大部分兼容,但 TP8.1 废弃部分过时方法,同时对时间格式、闭包查询有更严格的要求。

核心修改示例

TP5.0.24 数据库操作(旧代码):

use think\Db;

// 1. 查询操作
$userList = Db::name('user')
    ->where('status', 1)
    ->where('create_time', '>', time() - 7*24*3600)
    ->order('id desc')
    ->limit(10)
    ->select();

// 2. 新增数据
Db::name('user')->insert([
    'username' => 'test',
    'password' => md5('123456'),
    'create_time' => time(),
]);

// 3. 闭包查询
$list = Db::name('article')
    ->where(function($query) {
        $query->where('cat_id', 1)->orWhere('is_top', 1);
    })
    ->select();

TP8.1 数据库操作(新代码):

use think\facade\Db; // 推荐使用门面
use app\model\User;

// 1. 查询操作(时间格式要求标准datetime)
$userList = Db::name('user')
    ->where('status', 1)
    ->where('create_time', '>', date('Y-m-d H:i:s', time() - 7*24*3600))
    ->order('id', 'desc') // 显式指定排序方向(兼容旧写法,但推荐)
    ->limit(10)
    ->select();

// 2. 新增数据(推荐模型方式,自动处理时间戳)
$user = new User();
$user->save([
    'username' => 'test',
    'password' => password_hash('123456', PASSWORD_DEFAULT), // 废弃md5,推荐密码哈希
]);

// 3. 闭包查询(orWhere改为whereOr,兼容旧写法但推荐新标准)
$list = Db::name('article')
    ->where(function($query) {
        $query->where('cat_id', 1)->whereOr('is_top', 1);
    })
    ->select();

七、常见报错与代码修复对照表

升级后常见报错报错原因修复代码示例
Method 'success' not foundTP8.1 废弃控制器 success/error 快捷方法改用 Redirect 门面:$this->success('成功')return Redirect::to('/')->with('msg', '成功')
Invalid datetime format: 1292时间戳直接入库,TP8.1 要求标准 datetime 格式转换时间格式:time()date('Y-m-d H:i:s')
Class 'app\index\validate\User' not found验证器命名空间未按 TP8.1 规范调整命名空间修改:namespace app\index\validatenamespace app\validate
Call to undefined method think\Route::pattern()TP8.1 废弃 pattern() 方法替换为 rule() 方法:->pattern(['id' => '\d+'])->rule(['id' => '\d+'])
PHP Fatal error: Uncaught Error: Call to undefined function mb_strlen()TP8.1 依赖 mbstring 扩展,PHP8.0+ 需手动开启在 php.ini 中开启 extension=mbstring,重启 Web 服务

八、升级收尾:测试与优化

1. 兼容性测试:重点测试 PHP8.1 语法兼容(如废弃的 each() 函数、静态调用动态方法等);2. 功能测试:覆盖路由访问、数据增删改查、验证逻辑、关联查询等核心功能;3. 性能优化:执行 php think optimize:schema 生成数据库结构缓存,开启 OPcache 提升 PHP 执行效率;4. 安全优化:替换 md5 加密为 password_hash,检查并升级第三方扩展至兼容 PHP8.1 的版本。

相关文章

ThinkTemplate 模板引擎完全指南

ThinkTemplate 模板引擎完全指南ThinkTemplate 是 ThinkPHP 的内置模板引擎,现已支持独立使用。本文详细介绍其核心特性和使用方法。环境要求ThinkTemplate 3...

ThinkPHP3.2.3 升级 ThinkPHP8.1 实战指南

从 ThinkPHP3.2.3 跳跃升级至 ThinkPHP8.1,核心难点在于底层 API、语法规范、目录结构的大幅变更。本文覆盖控制器、模型、路由、验证、数据库操作等核心模块,通过“TP3.2.3...

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。