# 升級指導
# 5.1版本升級指導
本章節的內容告訴你進行`5.1.*`版本的升級須知和建議,由于一些必要原因,個別版本的升級并非完全無縫,請盡量按照本升級指導的建議進行調整。
- [從`5.1.14`升級到`5.1.15`](#51145115_6)
- [從`5.1.13`升級到`5.1.14`](#51135114_10)
- [從`5.1.12`升級到`5.1.13`](#51125113_23)
- [從`5.1.11`升級到`5.1.12`](#51115112_27)
- [從`5.1.10`升級到`5.1.11`](#51105111_31)
- [從`5.1.9`升級到`5.1.10`](#5195110_35)
- [從`5.1.8`升級到`5.1.9`](#518519_51)
- [從`5.1.7`升級到`5.1.8`](#517518_95)
- [從`5.1.6`升級到`5.1.7`](#516517_101)
- [從`5.1.5`升級到`5.1.6`](#515516_105)
- [從`5.1.0`升級到`5.1.5`](#510515_155)
- [從`5.0`升級到`5.1`](#5051_159)
## 從`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')];
```
表達式查詢方式不受影響。
> 如果你使用了閉包查詢條件,并且使用了默認的查詢緩存`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`
> 從`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`版本。
> 如非必要,在建項目請勿盲目升級,5.0版本依然持續維護中。
### 命名空間調整
如果你自定義了應用類庫的命名空間,需要改為設置環境變量`APP_NAMESPACE`而不是應用配置文件,如果你使用了`.env`配置文件,可以在里面添加:
```
APP_NAMESPACE = 你的應用類庫根命名空間名
```
然后,檢查你的應用類庫中`use`或者調用的系統類庫,如果使用了下面的系統類庫(主要涉及的類庫是`5.0`靜態調用的系統類庫),那么命名空間需要調整如下:
5.0系統5.1系統think\\Appthink\\facade\\App (或者 App )think\\Cachethink\\facade\\Cache (或者 Cache )think\\Configthink\\facade\\Config (或者 Config )think\\Cookiethink\\facade\\Cookie (或者 Cookie )think\\Debugthink\\facade\\Debug (或者 Debug )think\\Envthink\\facade\\Env (或者 Env )think\\Hookthink\\facade\\Hook (或者 Hook )think\\Langthink\\facade\\Lang (或者 Lang )think\\Logthink\\facade\\Log (或者 Log )think\\Requestthink\\facade\\Request (或者 Request )think\\Responsethink\\facade\\Response (或者 Response )think\\Routethink\\facade\\Route (或者 Route )think\\Sessionthink\\facade\\Session (或者 Session )think\\Urlthink\\facade\\Url (或者 Url )think\\Validatethink\\facade\\Validate (或者 Validate )think\\Viewthink\\facade\\View (或者 View )> 如果只是用于依賴注入則無需更改命名空間。
后面括號里面的類名使用是的根命名空間(`\`),這是因為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');
```
> 5\.1為系統的類庫注冊了類庫別名,因此可以直接從根命名空間方式調用Url。
所以路由配置文件在遷移到`5.1`版本后你可以直接刪除下面的一行代碼
```
use think\Route;
```
### 配置文件調整
原有的配置文件`config.php`從應用目錄移動到和應用目錄同級的`config`目錄,并拆分為`app.php`、`cache.php` 等獨立配置文件,系統默認的配置文件清單如下:
配置文件說明app.php應用配置文件cache.php緩存配置文件cookie.phpCookie配置文件database.php數據庫配置文件log.php日志配置文件session.phpSession配置文件template.php模板引擎配置文件trace.php頁面Trace配置文件> 換而言之就是原來所有的一級配置都獨立為一個配置文件
原來的應用`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');
```
`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)
```
對于純等于的數組條件則無需調整
```
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`方法進行過濾。
### 官方擴展
官方的下列`composer`擴展請升級到最新的`2.0`版本:
```
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`方法已經做了內部封裝,無需再使用`###`變量替換了。
> ### 最后一個步驟不要忘了:清空緩存目錄下的所有文件
- 序言
- 基礎
- 安裝
- 開發規范
- 目錄結構
- 配置
- 架構
- 架構總覽
- 入口文件
- URL訪問
- 模塊設計
- 命名空間
- 容器和依賴注入
- Facade
- 鉤子和行為
- 中間件
- 路由
- 路由定義
- 變量規則
- 路由地址
- 閉包支持
- 路由參數
- 路由緩存
- 跨域請求
- 注解路由
- 路由分組
- MISS路由
- 資源路由
- 快捷路由
- 路由別名
- 路由綁定
- 域名路由
- URL生成
- 控制器
- 控制器定義
- 前置操作
- 跳轉和重定向
- 空操作和空控制器
- 分層控制器
- 資源控制器
- 請求
- 請求對象
- 請求信息
- 輸入變量
- 請求類型
- HTTP頭信息
- 偽靜態
- 參數綁定
- 請求緩存
- 響應
- 響應輸出
- 響應參數
- 重定向
- 數據庫
- 連接數據庫
- 查詢構造器
- 查詢數據
- 添加數據
- 更新數據
- 刪除數據
- 查詢表達式
- 鏈式操作
- 聚合查詢
- 時間查詢
- 高級查詢
- 視圖查詢
- JSON字段
- 子查詢
- 原生查詢
- 查詢事件
- 事務操作
- 監聽SQL
- 存儲過程
- 數據集
- 分布式數據庫
- 模型
- 定義
- 新增
- 更新
- 刪除
- 查詢
- JSON字段
- 獲取器
- 修改器
- 自動時間戳
- 只讀字段
- 軟刪除
- 類型轉換
- 數據完成
- 查詢范圍
- 模型輸出
- 模型事件
- 模型關聯
- 一對一關聯
- 一對多關聯
- 遠程一對多
- 多對多關聯
- 多態關聯
- 關聯預載入
- 關聯統計
- 關聯輸出
- 視圖
- 視圖渲染
- 視圖賦值
- 視圖過濾
- 模板引擎
- 模板
- 變量輸出
- 使用函數
- 運算符
- 原樣輸出
- 模板注釋
- 模板布局
- 模板繼承
- 包含文件
- 輸出替換
- 標簽庫
- 內置標簽
- 循環標簽
- 比較標簽
- 條件判斷
- 資源文件加載
- 標簽嵌套
- 原生PHP
- 定義標簽
- 標簽擴展
- 錯誤和日志
- 異常處理
- 日志處理
- 調試
- 調試模式
- Trace調試
- 性能調試
- SQL調試
- 變量調試
- 遠程調試
- 驗證
- 驗證器
- 驗證規則
- 錯誤信息
- 驗證場景
- 路由驗證
- 內置規則
- 獨立驗證
- 靜態調用
- 表單令牌
- 雜項
- 緩存
- Session
- Cookie
- 多語言
- 分頁
- 上傳
- 命令行
- 啟動內置服務器
- 自動生成目錄結構
- 創建類庫文件
- 生成類庫映射文件
- 清除緩存文件
- 生成配置緩存文件
- 生成數據表字段緩存
- 生成路由映射緩存
- 自定義指令
- 擴展庫
- 驗證碼
- 圖像處理
- Time
- 數據庫遷移工具
- Workerman
- MongoDb
- 單元測試
- 安全和性能
- 安全建議
- 優化建議
- 附錄
- 助手函數
- 升級指導
- 更新日志