# 5.1版本升级指导
本章节的内容告诉你进行`5.1.*`版本的升级须知和建议,由于一些必要原因,个别版本的升级并非完全无缝,请尽量按照本升级指导的建议进行调整。
[TOC=2,2]
## 升级到`5.1.38`
视图渲染输出的时候,如果你需要获取渲染内容,需要改成
```
$html = $this->fetch()->getContent();
```
## 从`5.1.27`升级到最新版本
>[danger] 由于`5.1.27`已经是LTS版本,不会再出现不兼容的升级。
> 从`5.1.27`版本可以无缝升级到后续的`5.1.*`版本。
## 从`5.1.26`升级到`5.1.27`
从`5.1.26`版本可以无缝升级到`5.1.27`。
## 从`5.1.25`升级到`5.1.26`
从`5.1.25`版本可以无缝升级到`5.1.26`。
## 从`5.1.24`升级到`5.1.25`
从`5.1.24`版本可以无缝升级到`5.1.25`。
## 从`5.1.23`升级到`5.1.24`
从`5.1.23`版本可以无缝升级到`5.1.24`。
## 从`5.1.22`升级到`5.1.23`
从`5.1.22`版本可以无缝升级到`5.1.23`。
## 从`5.1.21`升级到`5.1.22`
从`5.1.21`版本可以无缝升级到`5.1.22`。
## 从`5.1.20`升级到`5.1.21`
从`5.1.20`版本可以无缝升级到`5.1.21`。
## 从`5.1.19`升级到`5.1.20`
从`5.1.19`版本可以无缝升级到`5.1.20`。
## 从`5.1.18`升级到`5.1.19`
从`5.1.18`版本可以无缝升级到`5.1.19`。
## 从`5.1.17`升级到`5.1.18`
从`5.1.17`版本可以无缝升级到`5.1.18`。由于取消了Test日志驱动,如果使用了Test日志驱动,请改为使用下面的配置全局关闭:
~~~
'close' => true,
~~~
## 从`5.1.16`升级到`5.1.17`
从`5.1.16`版本可以无缝升级到`5.1.17`。
## 从`5.1.15`升级到`5.1.16`
从`5.1.15`版本可以无缝升级到`5.1.16`。
> 不过注意一点,`Request`对象不再支持对请求变量的设置操作了,如果需要请使用 `$request->name` 的方式直接设置。
## 从`5.1.14`升级到`5.1.15`
从`5.1.14`版本可以无缝升级到`5.1.15`。
## 从`5.1.13`升级到`5.1.14`
从`5.1.13`版本基本可以无缝升级到`5.1.14`。
> 补充一点,如果动态配置设置`view_path`(在新版中不要动态配置,因为容器中的对象一旦实例化后是不会每次读取动态配置值的,减少依赖,也更方便单元测试),需要改成在控制器中调用:
> ~~~
> $this->view->config('view_path','path');
> ~~~
> 或者使用了view方法输出的话,可以使用
> ~~~
> think\facade\View::config('view_path','path');
> ~~~
## 从`5.1.12`升级到`5.1.13`
从`5.1.12`版本可以无缝升级到`5.1.13`。
## 从`5.1.11`升级到`5.1.12`
从`5.1.11`版本可以无缝升级到`5.1.12`。
## 从`5.1.10`升级到`5.1.11`
从`5.1.10`版本可以无缝升级到`5.1.11`。
## 从`5.1.9`升级到`5.1.10`
如果数组查询条件中使用了`exists`查询,必须做出如下调整:
~~~
// 错误
$where[] = ['', 'exists', 'select * from user where status = 0'];
// 正确
$where[] = ['', 'exists', Db::raw('select * from user where status = 0')];
~~~
建议的方式是使用
~~~
$model->whereExists('select * from user where status = 0')->select();
~~~
## 从`5.1.8`升级到`5.1.9`
从`5.1.8`升级到`5.1.9`的时候,请注意如下事项:
下面方式的数组条件查询不再使用索引数组
~~~
// 错误
$where['name'] = ['name', 'like', 'think'];
// 正确
$where[] = ['name', 'like', 'think'];
~~~
但对于基本条件查询不受影响
~~~
// 正确
$where['name'] = 'think';
~~~
但并不支持混合查询:
~~~
// 错误
$where['name'] = 'think';
$where[] = ['id', '<=', 10];
~~~
如果数组查询条件中使用了`exp`查询,必须做出如下调整:
~~~
// 错误
$where[] = ['id', 'exp', '>score'];
// 正确
$where[] = ['id', 'exp', Db::raw('>score')];
~~~
表达式查询方式不受影响。
>[danger] 如果你使用了闭包查询条件,并且使用了默认的查询缓存`cache()`或者`cache(true)`,新版本会抛出异常,请使用`cache('key')`替代,避免因为查询缓存无效而影响业务。
另外可能不影响但推荐使用的建议:
> `order/field/where`方法如果使用字符串参数并涉及到SQL函数的,推荐使用`orderRaw/fieldRaw/whereRaw`方法,或者对传入的字符串参数使用`Db::raw()`方法。
## 从`5.1.7`升级到`5.1.8`
从`5.1.7`版本可以无缝升级到`5.1.8`。
如果你从`5.1.5`直接升级的话,可以通过配置 `template.auto_rule` 参数为2,兼容之前的默认模板渲染规则。
## 从`5.1.6`升级到`5.1.7`
从`5.1.6`版本可以无缝升级到`5.1.7`。
## 从`5.1.5`升级到`5.1.6`
>[danger] 从`5.1.5`升级到`5.1.6`的过程需要注意如下事项:
### 路由变量规则调整
路由变量规则的定义不再支持使用模式修饰符和诸如`^\d+$`这种限定符。
例如
~~~
Route::rule('hello/:name','hello')
->pattern('name','/^\w{4}+$/i');
~~~
需要调整为
~~~
Route::rule('hello/:name','hello')
->pattern('name','\w{4}+');
~~~
### 路由标识用法调整
原来的
~~~
Route::name('路由标识')->rule('rule','route');
~~~
需要改成
~~~
Route::rule('rule','route')->name('路由标识');
~~~
### EXP表达式更新
出于安全性考虑,如果使用了`EXP`表达式更新,请使用`exp`方法替代数组方式。
### 默认模板渲染规则改进
由于`fetch`方法和`view`函数的默认模板规则调整为操作方法的名称(不含操作后缀)转换为小写+下划线方式,而不是原来的直接把操作名称转小写。
举个例子,你的控制器操作方法名如果是`helloWorld`,之前版本使用:
~~~
$this->fetch();
// 或者
view();
~~~
渲染输出的时候会定位到 `helloworld.html`模板文件,而新版会自动定位到`hello_world.html`模板文件。
> 对于指定模板渲染的`fetch`方法和`view`助手函数不受影响,对于非驼峰操作方法名也没有影响。
## 从`5.1.0`升级到`5.1.5`
从`5.1.0`版本可以无缝升级到`5.1.5`(包含以下任何一个版本)。
## 从`5.0`升级到`5.1`
由于`5.1`版本很多用法不同于`5.0`版本,本篇内容帮助你更顺利的从`5.0`版本迁移到`5.1`版本。
>[danger] 如非必要,在建项目请勿盲目升级,5.0版本依然持续维护中。
### 命名空间调整
如果你自定义了应用类库的命名空间,需要改为设置环境变量`APP_NAMESPACE`而不是应用配置文件,如果你使用了`.env`配置文件,可以在里面添加:
~~~
APP_NAMESPACE = 你的应用类库根命名空间名
~~~
然后,检查你的应用类库中`use`或者调用的系统类库,如果使用了下面的系统类库(主要涉及的类库是`5.0`静态调用的系统类库),那么命名空间需要调整如下:
|5.0系统|5.1系统|
|---|---|
| think\App | think\facade\App (或者 App )|
| think\Cache | think\facade\Cache (或者 Cache )|
| think\Config | think\facade\Config (或者 Config )|
| think\Cookie | think\facade\Cookie (或者 Cookie )|
| think\Debug | think\facade\Debug (或者 Debug )|
| think\Env | think\facade\Env (或者 Env )|
| think\Hook | think\facade\Hook (或者 Hook )|
| think\Lang | think\facade\Lang (或者 Lang )|
| think\Log | think\facade\Log (或者 Log )|
| think\Request | think\facade\Request (或者 Request )|
| think\Response | think\facade\Response (或者 Response )|
| think\Route | think\facade\Route (或者 Route )|
| think\Session | think\facade\Session (或者 Session )|
| think\Url | think\facade\Url (或者 Url )|
| think\Validate | think\facade\Validate (或者 Validate )|
| think\View | think\facade\View (或者 View )|
>[danger] 如果只是用于依赖注入则无需更改命名空间。
后面括号里面的类名使用是的根命名空间(`\`),这是因为5.1对常用的系统核心类库做了类库别名,举个例子,如果应用类库开头`use`了 `think\Url`
~~~
use think\Url;
Url::build('index/index');
~~~
则需要改成
~~~
use think\facade\Url;
Url::build('index/index');
~~~
或者
~~~
use Url;
Url::build('index/index');
~~~
>[info] 5.1为系统的类库注册了类库别名,因此可以直接从根命名空间方式调用Url。
所以路由配置文件在迁移到`5.1`版本后你可以直接删除下面的一行代码
~~~
use think\Route;
~~~
### 配置文件调整
原有的配置文件`config.php`从应用目录移动到和应用目录同级的`config`目录,并拆分为`app.php`、`cache.php` 等独立配置文件,系统默认的配置文件清单如下:
|配置文件|说明|
|---|---|
|app.php| 应用配置文件|
|cache.php|缓存配置文件|
|cookie.php|Cookie配置文件|
|database.php|数据库配置文件|
|log.php|日志配置文件|
|session.php|Session配置文件|
|template.php|模板引擎配置文件|
|trace.php|页面Trace配置文件|
>[info] 换而言之就是原来所有的一级配置都独立为一个配置文件
原来的应用`extra`目录下面的配置文件直接移动到`config`目录下面。
原来模块的配置文件(包括extra目录下面的)直接移动到模块下的`config`目录,然后参考上面的应用配置文件进行调整。
5.1的配置文件全部采用二级配置方式,所有**不带一级配置名的参数都会作为`app`的二级配置**,例如
~~~
config('app_debug');
~~~
等同于
~~~
config('app.app_debug');
~~~
> 并且注意,5.1的二级配置参数区分大小写。
一级配置`app`下的配置参数都在`app.php`配置文件中定义。
如果要获取数据库配置(`database.php`文件)的参数,则需要使用
~~~
config('database.hostname');
~~~
动态设置配置参数的时候,也要注意一级配置名
~~~
config('cache.type', 'memcache');
~~~
如果要获取一级配置下面的所有参数,使用
~~~
Config::pull('database');
// 或者使用
config('database.');
~~~
`view_replace_str`配置参数改成template配置文件的`tpl_replace_string`配置参数。
### 常量调整
`5.1`取消了所有的框架内置常量(不影响应用代码中的自定义常量),如需获取,请使用`think\facade\App`类的内置方法以及`think\facade\Env`类获取,下面给出的是`5.0`和`5.1`的常量对照表:
|5.0常量|5.1获取方法|
|---|---|
|EXT| 取消,固定使用 `.php`|
|IS_WIN|取消|
|IS_CLI|取消|
|DS | 使用PHP自带 `DIRECTORY_SEPARATOR`|
|ENV_PREFIX|取消,固定使用`PHP_`|
|THINK_START_TIME|`App::getBeginTime()`|
|THINK_START_MEM|`App::getBeginMem()`|
|THINK_VERSION| `App::version()`|
|THINK_PATH|`Env::get('think_path')`|
|LIB_PATH|`Env::get('think_path') . 'library/'`|
|CORE_PATH|`Env::get('think_path') . 'library/think/'`|
|APP_PATH|`Env::get('app_path')`|
|CONFIG_PATH| `Env::get('config_path')`|
|CONFIG_EXT|`App::getConfigExt()`|
|ROOT_PATH|`Env::get('root_path')`|
|EXTEND_PATH| `Env::get('root_path') . 'extend/'` |
|VENDOR_PATH| `Env::get('root_path') . 'vendor/'` |
|RUNTIME_PATH|`Env::get('runtime_path')`|
|LOG_PATH| `Env::get('runtime_path') . 'log/'` |
|CACHE_PATH| `Env::get('runtime_path') . 'cache/'` |
|TEMP_PATH| `Env::get('runtime_path'). 'temp/'` |
|MODULE_PATH|`Env::get('module_path')`|
通过`Env`类的`get`方法获取路径变量的时候不区分大小写,例如下面的写法是等效的:
~~~
Env::get('root_path');
Env::get('ROOT_PATH');
~~~
### 路由调整
原有的路由定义文件`route.php` 移动到应用目录同级的`route`目录下面,如果有定义其它的路由配置文件,一并放入`route`目录即可(无需更改文件名)。
`url_route_on`配置参数无效,会始终检查路由,没有定义路由的情况下默认解析方式依然有效。
原来的`before_behavior`和`after_behavior`参数更改为`before`和`after`,并且路由缓存功能暂时取消。
Route类的`rule`方法不再支持批量注册路由,请使用`Route::rules`方法替代。
如果使用了domain方法批量绑定模块,需要改为单独绑定,原来的用法:
~~~
Route::domain([
'a' => 'a',
'b' => 'b'
]);
~~~
需要改为:
~~~
Route::domain('a','a');
Route::domain('b','b');
~~~
### 数据库调整
* 取消了Query类的`getTableInfo`方法,可以用更加具体的`getTableFields`
或者`getFieldsType`方法替代;
* 数据库查询后`5.1`不会清空查询条件;
* 取消了`select(false)` 用法,使用 `fetchSql()->select()` 替代;
* 如果使用了mysql的JSON查询语法,`user$.name` 需要改为 `user->name`;
* 改变了查询构造器的数组多字段批量查询,从原来的
~~~
where([
'name' => ['like','think%'],
'id' => ['>',0],
])
~~~
需要调整为
~~~
where([
['name','like','think%'],
['id','>',0],
])
~~~
或者使用表达式语法
~~~
where('name','like','think%')->where('id','>',0)
~~~
对于纯等于的数组条件则无需调整
~~~php
where(['name'=>'think', 'type'=>1])
~~~
### 模型调整
为了确保模型的用法统一,对模型进行了一些调整,包括:
* 模型的数据集查询始终返回数据集对象而不再是数组;
* 模型的数据表主键如果不是`id`,则必须设置模型的`pk`属性;
* 软删除trait引入更改为 `use think\model\concern\SoftDelete`;
* 全局查询范围`base`方法中无需添加软删除条件;
* 聚合模型功能废除,使用关联模型配合关联自动写入功能替代,更灵活;
* 模型的查询范围`scope`方法调用后只能使用数据库的查询方法;
* 取消模型的数据验证功能,请使用控制器验证或者路由验证替代;
### 控制器调整
为了规范化,继承了`think\Controller`类的话,初始化方法从原来的`_initialize`方法更改为`initialize`。
`fetch`方法以及`view`助手函数的`replace`参数废弃,如果需要模板替换功能,改成template配置文件的`tpl_replace_string`配置参数。或者使用`filter`方法进行过滤。
### 验证类调整
验证规则的错误信息定义不再支持规则和错误信息定义在一起,例如:
```
namespace app\index\validate;
use think\Validate;
class User extends Validate
{
protected $rule = [
['name','require|max:25','名称必须|名称最多不能超过25个字符'],
['age','number|between:1,120','年龄必须是数字|年龄必须在1~120之间'],
['email','email','邮箱格式错误']
];
}
```
需要调整为
```
namespace app\index\validate;
use think\Validate;
class User extends Validate
{
protected $rule = [
'name' => 'require|max:25',
'age' => 'number|between:1,120',
'email' => 'email',
];
protected $message = [
'name.require' => '名称必须',
'name.max' => '名称最多不能超过25个字符',
'age.number' => '年龄必须是数字',
'age.between' => '年龄必须在1~120之间',
'email' => '邮箱格式错误',
];
}
```
### 官方扩展
官方的下列`composer`扩展请升级到最新的`2.0`版本:
~~~cmd
topthink/think-captcha
topthink/think-mongo
topthink/think-migration
topthink/think-testing
topthink/think-queue
~~~
### 其它注意事项
`Request`类不再需要`instance`方法,直接调用类的方法即可。
废弃了`Rest`控制器扩展,建议更改为资源控制器的方式。
原来内置的其它控制器扩展,请自行在应用里面扩展。
因为严格遵循`PSR-4`规范,不再建议手动导入类库文件,所以新版取消了`Loader::import`方法以及`import`和`vendor`助手函数,推荐全面采用命名空间方式的类以及自动加载机制,如果必须使用请直接改为php内置的`include`或者`require`语法。
为了保持`Loader`类库的单纯性,原`Loader`类的`controller`、`model`、`action`和`validate`方法改为`App`类的同名方法,助手函数用法保持不变。
模板的变量输出默认添加了`htmlentities`安全过滤,如果你需要输出html内容的话,请使用`{$var|raw}`方式替换,并且`date`方法已经做了内部封装,无需再使用`###`变量替换了。
>[danger]### 最后一个步骤不要忘了:清空缓存目录下的所有文件
- 序言
- 基础
- 安装
- 开发规范
- 目录结构
- 配置
- 架构
- 架构总览
- 入口文件
- URL访问
- 模块设计
- 命名空间
- 容器和依赖注入
- Facade
- 钩子和行为
- 中间件
- 路由
- 路由定义
- 变量规则
- 路由地址
- 闭包支持
- 路由参数
- 路由缓存
- 跨域请求
- 注解路由
- 路由分组
- MISS路由
- 资源路由
- 快捷路由
- 路由别名
- 路由绑定
- 域名路由
- URL生成
- 控制器
- 控制器定义
- 前置操作
- 跳转和重定向
- 空操作和空控制器
- 分层控制器
- 资源控制器
- 控制器中间件
- 请求
- 请求对象
- 请求信息
- 输入变量
- 请求类型
- HTTP头信息
- 伪静态
- 参数绑定
- 请求缓存
- 响应
- 响应输出
- 响应参数
- 重定向
- 文件下载
- 数据库
- 连接数据库
- 查询构造器
- 查询数据
- 添加数据
- 更新数据
- 删除数据
- 查询表达式
- 链式操作
- where
- table
- alias
- field
- strict
- limit
- page
- order
- group
- having
- join
- union
- distinct
- lock
- cache
- comment
- fetchSql
- force
- partition
- failException
- sequence
- 聚合查询
- 时间查询
- 高级查询
- 视图查询
- JSON字段
- 子查询
- 原生查询
- 查询事件
- 获取器
- 事务操作
- 监听SQL
- 存储过程
- 数据集
- 分布式数据库
- 模型
- 定义
- 新增
- 更新
- 删除
- 查询
- JSON字段
- 获取器
- 修改器
- 搜索器
- 数据集
- 自动时间戳
- 只读字段
- 软删除
- 类型转换
- 数据完成
- 查询范围
- 模型输出
- 模型事件
- 模型关联
- 一对一关联
- 一对多关联
- 远程一对多
- 多对多关联
- 多态关联
- 关联预载入
- 关联统计
- 关联输出
- 视图
- 视图渲染
- 视图赋值
- 视图过滤
- 模板引擎
- 模板
- 变量输出
- 使用函数
- 运算符
- 原样输出
- 模板注释
- 模板布局
- 模板继承
- 包含文件
- 输出替换
- 标签库
- 内置标签
- 循环标签
- 比较标签
- 条件判断
- 资源文件加载
- 标签嵌套
- 原生PHP
- 定义标签
- 标签扩展
- 错误和日志
- 异常处理
- 日志处理
- 调试
- 调试模式
- Trace调试
- 性能调试
- SQL调试
- 变量调试
- 远程调试
- 验证
- 验证器
- 验证规则
- 错误信息
- 验证场景
- 路由验证
- 内置规则
- 独立验证
- 静态调用
- 表单令牌
- 杂项
- 缓存
- Session
- Cookie
- 多语言
- 分页
- 上传
- 命令行
- 启动内置服务器
- 查看版本
- 自动生成目录结构
- 创建类库文件
- 生成类库映射文件
- 清除缓存文件
- 生成配置缓存文件
- 生成数据表字段缓存
- 生成路由映射缓存
- 输出路由定义
- 自定义指令
- 扩展库
- 验证码
- 图像处理
- Time
- 数据库迁移工具
- Swoole
- Workerman
- MongoDb
- 单元测试
- 安全和性能
- 安全建议
- 优化建议
- 附录
- 助手函数
- 升级指导
- 更新日志