thinkphp5.1 php7,空白目錄 · 細數ThinkPHP5.1.7版本新特性 · 看云

>[danger] 官方已經在前不久發布了ThinkPHP`5.1.7`版本,`5.1`版本相較于`5.0`版本而言,本身更加嚴謹和規范,更接近主流設計思想。近半年來,`5.1`版本更新頻繁,此次最新版本更是帶來了很多的新特性。正在或者打算使用`5.1`版本的朋友可以關注下了,因為經過此次更新后,`5.1`版本也進入穩定階段了,基本上不太會有大的調整了。

最新版本(`V5.1.7`)的主要新特性主要包含:

[TOC=2,2]

## 引入中間件支持

關于中間件想必很多開發者已經在其它的主流框架中了解到了,ThinkPHP`5.1`版本最開始沒有引入中間件的原因是考慮到用戶需要了解新的知識概念和用法,同時容易和原來的行為用法相混淆。

>[info] 為了更規范開發和最大程度的公用某些組件,新版正式引入中間件支持。

原來你可能需要在控制器的初始化方法中添加相類似的代碼,現在你可以把這些代碼從控制器中獨立出來,方便更多的模塊調用和重用。如果你原來使用的是行為來進行處理的話,那么是否決定也改為中間件完全取決于你自己,因為仍然可以兼容運行(至少在`5.1`版本中不會變化)。

中間件的基本用法我大概介紹下:

### 定義中間件

可以通過命令行指令快速生成中間件類

~~~

php think make:middleware Check

~~~

這個指令會 `application/http/middleware`目錄下面生成一個`Check`中間件,也就是說默認生成的中間件的命名空間都是`app\http\middleware`,這個必須注意。

~~~

namespace app\http\middleware;

class Check

{

public function handle($request, \Closure $next)

{

}

}

~~~

中間件的入口執行方法必須是`handle`方法,而且第一個參數是`Request`對象,第二個參數是一個閉包。

>[danger] 中間件`handle`方法的返回值必須是一個`Response`對象。

### 前置/后置中間件

中間件是在請求具體的操作之前還是之后執行,完全取決于中間件的定義本身。

下面是一個前置行為的中間件

~~~

namespace app\http\middleware;

class Before

{

public function handle($request, \Closure $next)

{

// 添加中間件執行代碼

return $next($request);

}

}

~~~

下面是一個后置行為的中間件

~~~

namespace app\http\middleware;

class After

{

public function handle($request, \Closure $next)

{

$response = $next($request);

// 添加中間件執行代碼

return $response;

}

}

~~~

### 注冊中間件

第一種方式:注冊全局中間件

你可以在應用目錄下面定義`middleware.php`文件,使用下面的方式:

~~~

return [

\app\http\middleware\Auth::class,

'Check',

'Hello',

];

~~~

中間件的注冊應該使用完整的類名,如果沒有指定命名空間則使用`app\http\middleware`作為命名空間。

全局中間件的執行順序就是定義順序。可以在定義全局中間件的時候傳入中間件參數,支持兩種方式傳入。

~~~

return [

[\app\http\middleware\Auth::class, 'admin'],

'Check',

'Hello:thinkphp',

];

~~~

上面的定義表示 給`Auth`中間件傳入`admin`參數,給`Hello`中間件傳入`thinkphp`參數。

### 路由中間件

最常用的中間件注冊方式是注冊路由中間件

~~~

Route::rule('hello/:name', 'hello')

->middleware('Auth');

~~~

或者使用完整的中間件類名

~~~

Route::rule('hello/:name', 'hello')

->middleware(app\http\middleware\Auth::class);

~~~

支持對路由分組注冊中間件

~~~

Route::group('hello', function(){

Route::rule('hello/:name', 'hello');

})->middleware('Auth');

~~~

如果需要傳入額外參數給中間件,可以使用

~~~

Route::rule('hello/:name', 'hello')

->middleware('Auth:admin');

~~~

如果使用的是常量方式定義,可以在第二個參數傳入中間件參數。

~~~

Route::rule('hello/:name', 'hello')

->middleware(Auth::class, 'admin');

~~~

>[danger] 中間件方法參數只能有一個,但可以支持任意類型,在`handle`方法的第三個參數傳入即可。

如果你不希望每次在路由中注冊完整的類名,還可以在應用配置文件`middleware.php`中進行中間件的預定義,指定中間件的別名。

~~~

return [

'auth' =>'app\http\middleware\Auth',

'check'=>[

'user'=> app\common\middleware\CheckUser::class

],

];

~~~

然后,在路由中使用別名注冊中間件。

~~~

Route::rule('hello/:name', 'hello')

->middleware(['auth', 'check.user']);

~~~

好了,更多的中間件用法還需要你親自實踐。

## 路由改進和提速

新版本的路由改進是最多的(幾乎整個過年都在調整路由組件^_^),我們知道路由無非是兩大要點,路由定義和路由檢測。

路由定義涉及到一個規范化的問題,新版路由在保持原來的用法前提下,內部做了一些架構和細節的調整,使得路由的用法更加對象化。如果你看源碼的話,就會發現核心類庫的`route`目錄下面新增了幾個類。

### 路由規則的變量用法改進

路由定義方面主要對域名路由和路由分組的功能進行了強化,以及路由規則的更靈活定義。

之前的路由規則中變量分兩種,普通變量和組合變量定義,新版把這兩種合二為一了(也就是說兩種變量沒有任何區別,僅僅是表現方式不同,而且是出于兼容考慮)。你現在完全可以在路由規則中以任何方式定義路由變量。

例如你可以使用下面的路由規則而不用管目前的URL分隔符是什么:

~~~

Route::rule('item/:name_:id', 'order/index');

Route::rule('product-:name', 'product/item');

~~~

另外,新版路由定義兩種變量方式`:name`和` `可以混合使用,但建議統一使用``,在性能上略有優勢(實際上,最終解析的時候系統會統一解析成后者)。

### 路由匹配算法改進

路由檢測其實是最耗性能的,尤其是路由匹配這塊,因為基本上都是采用的正則匹配。在`5.1.6`版本之前,如果定義了100個路由,那么最后的那個路由規則可能需要遍歷100次才能正確匹配到路由,而且每個路由規則中的路由變量都是單獨匹配的,所以這個路由匹配的性能開銷是隨著路由定義的數量指數上升的。

`5.1.6`版本開始,系統對路由的匹配這塊進行了算法優化,靈感來自于`fastRoute`。基本思想是分兩個步驟優化(思想其實很容易懂,但技術層面比較復雜,所以想了解怎么實現的話還是仔細看代碼吧~本文只闡述思想)。

第一個步驟是對單個路由規則的匹配算法進行調整,不按照變量進行多次匹配,而是把路由變量的正則合并到一起,然后整個路由規則只匹配一次(如果這個路由規則都是靜態的,那么基本上不需要正則匹配,采用的是更快的非正則檢測方式)。這個是新版默認就開啟的,相比較之前的版本,性能已經提升明顯。

但路由的性能提速遠非如此簡單,第二個步驟的優化策略是如果當前匹配的路由分組下面有多個路由規則(確切的說是滿足當前請求類型的),則把這些滿足條件的路由規則合并成一個正則表達式進行路由匹配。如果你的路由分組下面有100個滿足條件的路由規則,如果要訪問最后的路由規則,之前的方式可能需要遍歷100次,而新版只需要進行一次匹配。就算加上路由規則的合并開銷,仍然是值得的。

如果需要使用分組路由規則的全局合并檢測,需要開啟下面的設置(另外一個方式是單獨對某個路由分組使用`mergeRuleRegex`方法,這種需求應該不多):

~~~

// 合并分組路由規則

'route_rule_merge' => true,

~~~

那么到這是不是就結束了呢?不要忘了ThinkPHP`5.1`的路由有一個很創新的地方就是延遲解析,主要體現在路由分組或者域名路由。通常的路由定義是需要把定義的路由進行一次解析處理,然后保存成我們方便檢測的一個數據結構或者對象,但由于WEB請求的特殊性,每次請求都需要重復這種路由定義的解析過程,為了降低路由解析的開銷,ThinkPHP只會在路由分組匹配之后才會實際去進行該路由分組下面的路由解析過程,然后再進行后續的路由檢測,如果你的分組下面還有子分組,那么繼續按照這個方式解析。

不過路由的延遲解析功能默認是關閉的,可以在應用配置中開啟:

~~~

// 開啟路由延遲解析

'url_lazy_route' => true,

~~~

通過這三個步驟的優化,我相信現在你應該明白如何利用路由規則的合并以及路由的延遲解析機制來提升你的路由性能了吧。

如果你繼續深入路由的使用,還會發現一些細節的用法。

## 查詢安全性改進

接下來要講的是新版對于查詢安全性的一個改進,引入了一個新的`Expression`類,對于這種類型的數據,在查詢和寫入操作的時候會保持原樣`SQL`(比較適合于使用SQL函數的情況),并且同時支持參數綁定功能。

為了方便,`Query`類增加了`raw`方法用于實例化一個`Expression`對象,我們可以這樣使用:

~~~

Db::name('user')

->field(Db::raw('id, name'))

->where(Db::raw('id > :id AND status = 1'), ['id' => 1])

->order(Db::raw('id desc'))

->select();

~~~

系統在解析的時候,支持對`field/where/order`方法的`Expression`對象的解析。

同時為了方便使用,提供了一些快捷方法,例如上面的例子可以改為:

~~~

Db::name('user')

->fieldRaw('id, name')

->whereRaw('id > :id AND status = 1', ['id' => 1])

->orderRaw('id desc')

->select();

~~~

> 當然,大部分情況下,系統會自動判斷是否需要使用`Expression`表達式對象,從而避免數據出現安全隱患。例如,當你使用字符串條件,并且包含空格和函數用法的話,會自動解析為`Expression`對象執行查詢。

在數據寫入方面一樣可以利用表達式方式來杜絕可能的安全隱患,例如:

~~~

Db::name('user')

->save($data);

~~~

當你的`data`數據直接來自于表單提交數據的時候,會導致SQL注入的可能,新版會檢查數組數據的安全性,對`exp`表達式寫入進行更嚴格的類型檢查。

原來的`exp`數組用法將不可用,而必須改為:

~~~

Db::name('user')

->where('id', 1)

->save([

'score'=>['exp', Db::raw('score+1')],

]);

~~~

或者直接使用`exp`方法更新數據

~~~

Db::name('user')

->where('id', 1)

->exp('score', 'score+1')

->save();

~~~

這些查詢的安全特性同樣對模型適用,比如你需要使用SQL更新數據的時候,可以使用

~~~

$user = User::get(1);

$user->name = Db::raw('UPPER("thinkphp")');

$user->score = Db::raw('score+1');

$user->save();

~~~

新版的特性暫時就介紹這么多,還有一些細節等待各位去挖掘和分享。

> 本文使用了看云文檔的單頁文檔功能,有興趣的可以多了解下,并且多使用看云進行一些技術的分享和電子出版。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/259546.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/259546.shtml
英文地址,請注明出處:http://en.pswp.cn/news/259546.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

JS中popup.js

為什么80%的碼農都做不了架構師?>>> //popup class 顯示彈出窗口,。/*以下為使用popup對象,傳入相應的配置參數,彈出不同類型的窗口 function ShowIframe() //顯示iframe { var popnew P…

圖像連通域標記算法研究

搬以前寫的博客【2014-03-01 08:09】 圖像連通域標記算法研究 ConnectedComponent Labeling 最近在研究一篇復雜下背景文字檢測的論文。 “Detecting Text in Natural Scenes with Stroke Width Transform ” CPVR 2010的文章,它主要探討利用文字內…

lightoj 1214

lightoj 1214 Large Division (大數除法) 鏈接:http://www.lightoj.com/volume_showproblem.php?problem1214 題意:給定 a, b 兩個數,判斷 a 是否整除 b 。(a 為 大數) 思路&#…

二階振蕩衰減 matlab,基于Matlab/Simulink的二階控制系統仿真研究

1 二階控制系統模型本文引用地址:http://www.eepw.com.cn/article/201612/328597.htm能夠用二階微分方程描述的系統稱為二階控制系統。在控制工程實踐中,二階控制系統十分常見,例如,電樞控制的直流電動機,RLC網絡和彈簧…

CCF201409-5 拼圖(30分)

試題編號: 201409-5 試題名稱: 拼圖 時間限制: 3.0s 內存限制: 256.0MB 問題描述: 問題描述給出一個nm的方格圖,現在要用如下L型的積木拼到這個圖中,使得方格圖正好被拼滿,請問總共有…

歐幾里得算法(即輾轉相除法)的時間復雜度

本文是參考新浪博客而寫。 歐幾里得算法, 又稱輾轉相除法, 用于求兩個自然數的最大公約數. 算法的思想很簡單, 基于下面的數論等式 gcd(a, b) gcd(b, a mod b) 其中gcd(a, b)表示a和b的最大公約數, mod是模運算, 即求a除以b的余數. 代碼如下: #include <iostream> #i…

UIImageJPEGRepresentation和UIImagePNGRepresentation

在Iphone上有兩種讀取圖片數據的簡單方法: UIImageJPEGRepresentation和UIImagePNGRepresentation. UIImageJPEGRepresentation函數需要兩個參數:圖片的引用和壓縮系數.而UIImagePNGRepresentation只需要圖片引用作為參數.通過在實際使用過程中,比較發現: UIImagePNGRepresenta…

C++ 0x

轉載于:https://www.cnblogs.com/iiiDragon/p/3230006.html

系列文章----.Net程序員學用Oracle系列

.Net程序員學用Oracle系列(18)&#xff1a;PLSQL Developer 攻略.Net程序員學用Oracle系列(17)&#xff1a;數據庫管理工具(SQL Plus).Net程序員學用Oracle系列(16)&#xff1a;訪問數據庫(ODP.NET).Net程序員學用Oracle系列(15)&#xff1a;DUAL、ROWID、NULL.Net程序員學用Or…

Github for Windows使用介紹

Git已經變得非常流行&#xff0c;連Codeplex現在也已經主推Git。Github上更是充斥著各種高質量的開源項目&#xff0c;比如ruby on rails&#xff0c;cocos2d等等。對于習慣Windows圖形界面的程序員來講&#xff0c;Github的使用是需要點時間和耐心的&#xff0c;然而最近Githu…

matlab中udt函數,《MATLAB信號處理超級學習手冊》——2.5 離散時間信號中的運算...

本節書摘來自異步社區《MATLAB信號處理超級學習手冊》一書中的第2章&#xff0c;第2.5節&#xff0c;作者&#xff1a;MATLAB技術聯盟 , 史潔玉著&#xff0c;更多章節內容可以訪問云棲社區“異步社區”公眾號查看2.5 離散時間信號中的運算MATLAB信號處理超級學習手冊2.5.1 離散…

iOS 將16進制顏色轉換成UIColor

很多地方我們都使用16進制顏色&#xff0c;但iPhone使用的是UIColor對象&#xff0c;不直接支持16進制顏色&#xff0c;為此&#xff0c;需要我們手動將16進制顏色轉換為UIColor - (UIColor *) hexStringToColor: (NSString *) stringToConvert {NSString *cString [[stringTo…

OBJ 文件格式

OBJ文件是一種標準的3D模型文件格式&#xff0c;很適合用于3D軟件模型之間的互導。比如在3dsMax或LightWave中建了一個模型&#xff0c;想把它調到Maya里面渲染或動畫&#xff0c;導出OBJ文件就是一種很好的選擇。目前幾乎所有知名的3D軟件都支持OBJ文件的讀寫&#xff0c;不過…

構建Docker鏡像(三)

作者:李曉輝聯系方式:Xiaohui_lifoxmail.comQQ:939958092一、建立Dockerfile1、準備文件新建一個目錄和一個 Dockerfilemkdir /steventouch /steven/Dockerfile2、更新Dockerfile這個步驟是在設計鏡像&#xff0c;如果你需要在鏡像內包含什么軟件&#xff0c;將來開放哪些端口&…

centos 配置php開發環境變量配置,CentOS中配置PHP和Nginx環境變量

搜索熱詞一、摘要在Linux CentOS系統上 安裝完PHP和Nginx后&#xff0c;一般需要執行查看版本命令’PHP -v’和’Nginx -v’,確認是否安裝成功,如果在沒有添加到環境變量之前&#xff0c;執行“PHP -v”命令查看當前PHP版本信息時&#xff0c;則會提示命令不存在的錯誤&#xf…

你必須很努力,才能看上去毫不費力

世上沒有一件工作不辛苦&#xff0c;沒有一處人事不復雜。 從今天起&#xff0c;每天微笑吧&#xff0c; 世上除了生死&#xff0c;都是小事。 不管遇到了什么煩心事&#xff0c;都不要自己為難自己&#xff1b; 無論今天發生多么糟糕的事&#xff0c;都不應該感到悲傷。 今天是…

HDU 4631 Sad Love Story 平面內最近點對

http://acm.hdu.edu.cn/showproblem.php?pid4631 題意: 在平面內依次加點,求每次加點后最近點對距離平方的和 因為是找平面最近點對...所以加點以后這個最短距離一定是遞減的...所以最后會形成這樣一個函數圖像 所以我們只要從后往前依次刪點即可... 15秒驚險水過...不過我最小…

c++三/五法則

如果這個類需要一個析構函數&#xff0c;我們幾乎可以肯定它也需要一個拷貝構造函數和一個拷貝賦值運算符。 如果一個類需要拷貝構造函數&#xff0c;幾乎可以肯定它也需要一個拷貝賦值運算符&#xff0c;反之亦然。 然而&#xff0c;無論是需要拷貝構造函數還是需要拷貝賦值運…

itoa的用法

功能&#xff1a;將任意類型的整數轉換為字符串。在<stdlib.h>中與之有相反功能的函數是atoi。 用法&#xff1a;char*itoa(int value,char*string,int radix); int value 被轉換的整數&#xff0c;char *string 轉換后儲存的字符數組&#xff0c;int radix 轉換進制數…

Tomcat與Gzip與緩存

國內私募機構九鼎控股打造APP&#xff0c;來就送 20元現金領取地址&#xff1a;http://jdb.jiudingcapital.com/phone.html內部邀請碼&#xff1a;C8E245J &#xff08;不寫邀請碼&#xff0c;沒有現金送&#xff09;國內私募機構九鼎控股打造&#xff0c;九鼎投資是在全國股份…