下面thinkphp框架教程欄目將給大家介紹關于thinkphp5.1中間件在控制器中的使用過程,希望對需要的朋友有所幫助!
ThinkPHP5.1中間件在控制器中使用過程
使用中間件的開始以及我的步驟描述,希望可以幫到才學php 或者才學think框架的你們希望能夠與你們交流,讓自己進步。
中間件在Thinkphp框架中的作用我已經明白了,就是在請求即將達到應用層之前,對用戶訪問資源時候,產生的header頭 或者 用戶的請求參數時候輸入的post 或get 或者別的請求類型,以及url 路徑進行操作,其中包括了前置或者后置操作或者執行順序等方案。在理解后覺得這個東西在處理用戶請求數據的時候有極大的作用,比之直接在控制器或者在行為里面處理好了很多。(于是懷著滿滿的激動心情閱讀5.1的文檔手冊)。
在閱讀完文檔后,按照官方手冊的方法,在命令行中敲出如下代碼:
php think make:middleware Check
這段代碼的意思沒有任何問題就是生產一個中間件目錄以及創建一個新的名字為Check中間件文件
該內容正常完成沒有問題
按照文檔要求方案粘貼了5.1的文檔代碼
完全照著手冊復制的,沒有任何問題,確認進行了保存以及任何錯誤。
在此確認在我的admin模塊根目錄下放置了一個名字為 middleware.php的文件 如下圖所示
,就這樣進行一個注冊,那么這個模塊下如果想使用中間件,就可以使用了。
然后我在控制器內按照文檔手冊中的內容,根據控制器中間件內容描述加入了如圖所示的代碼
,
結果發現,代碼沒有被執行,納悶的我摸了摸腦袋,按照我的理解應,如果這么做了的話,應該可以直接應用了才對的,結果對象是個空的。無奈下,按照自己的理解,我在中間件內停止了代碼
在看到自己希望看到的內容后,再次測試我的$request。 看到了我期待已久的東西,我的中間件好了
至此以上步驟告訴我,第一步已經完成,我現在可以使用一個中間件做我想做的事情了
第一步 先吧名字變成我想變得 這里有三處改動的地方。
再次刷新后發現依然可以使用,絕對溜溜的跑起來。在這一步中,也堅定了我的一些使用想法,比如創造多個中間件,每個控制器都應該有一個相對應的,在這里執行一些自己象處理的,在看到手冊上還可以使用各種其他的方法,包括執行順序的改變,這讓我心中各種意淫。從此代碼變得又可以稍微高大上一點了。
第二步 建立功能規則 配合Config配置中的自建文件,對訪問進行控制
<?php namespace apphttpmiddleware; use thinkfacadeConfig; use thinkfacadeRequest; /** 登陸接口通用數據配置檢測*/ class AdminLoginCheck { /** * handle 重寫處理請求對象的操作函數 * @param object Request $request 請求對象 * @param object Closure $next 響應對象 * @return array 錯誤返回的信息 * code 返回碼 * msg 返回信息 * data 返回數據 * @return object 響應對象 */ public function handle($request, Closure $next) { // 檢測配置,查看該接口服務是否被暫停使用 if (true !== Config::get(Request::module().'.'.Request::action().'.'.Request::action().'_api')) // 如果結果不符合要求則返回錯誤信息 exit(json_encode(['code'=>1,'msg'=>'Interface_Pause_service','data'=>''])); // 檢測配置,是否執行請求驗證類型 if (false !== Config::get(Request::module().'.'.Request::action().'.'.Request::action().'_request')) { // 登陸請求規則,傳入相應方法,查看該接口是否符合請求類需 $res = self::loginRequestRole(Request::action()); // 如果結果不符合要求則返回錯誤信息 if (true !== $res) exit(json_encode(['code'=>1,'msg'=>'Request_Type_Not_Matching','data'=>''])); } // 檢測配置,是否執行地址限制驗證 if (false !== Config::get(Request::module().'.'.Request::action().'.'.Request::action().'_address')) { // 客戶端訪問地址限制請求規則 $res = self::loginAddressDispose(Request::ip()); // 如果結果不符合要求則返回錯誤信息 if (true !== $res) exit(json_encode(['code'=>1,'msg'=>'Address_Not_Access','data'=>''])); } // 格式化與處理前臺參數 $request = self::loginParamDispose(Request::action(),$request); // 繼續執行進入到控制器 return $next($request); } /** * loginRequestRole 請求類型驗證 * @param string $scene 根據路徑傳入方法名稱 * @return bool 驗證用戶訪問的接口是否符合預設的請求要求 */ protected static function loginRequestRole($scene) { switch ($scene) { // 登陸頁面請求驗證 case 'index': if (Request::isGet()) return true; else return false; break; // 登陸接口請求驗證 case 'login': if (Request::isPost() || Request::isAjax() || Request::isPjax()) return true; else return false; break; // 登陸接口請求驗證 case 'resetPassword': if (Request::isPost() || Request::isAjax() || Request::isPjax()) return true; else return false; break; // 默認驗證或者不存在的場景返回 default: return false; break; } } /** * loginAddressDispose 地址是否允許訪問 * @param string $address 需要傳入一個address地址 * @return string 返回錯誤信息 * @return bool 檢測正確返回真 */ protected static function loginAddressDispose($address) { // 讀取配置內的設置參數 $data = Config::get(Request::module().'.'.Request::action().'.'.Request::action().'_address_data'); // 如果配置信息address列表為空則返回不能訪問 if (empty($data)) return false; // 循環地址列表信息解開連續address地址列表 foreach ($data as $key => $val) { if ($val == $address) return true; } // 如果繼續執行下去依然沒有 返回不能訪問 return false; } /** * loginParamDispose post內容與格式處理 * @param string $scene 需要前往的接口名稱 * @param object $request 請求的對象內容 * @return object 返回處理過的請求對象 */ protected static function loginParamDispose($scene,$request) { switch ($scene) { // 登陸頁面 case 'index': break; // 登陸接口請求參數處理 case 'login': // 前臺用戶傳入的參數進行調整轉換 $request->username = $request->param('user'); $request->password = $request->param('pass'); $request->captcha = $request->param('code'); // 對記住我進行處理 $remember = $request->param('remember'); if (null === $remember) $request->remember = 'shut'; else $request->remember = 'open'; break; // 重置密碼接口參數處理 case 'resetPassword': // 前臺用戶傳入的參數進行調整轉換 $request->username = $request->param('user'); $request->phone = $request->param('mobile'); $request->phonecode = $request->param('code'); $request->password = $request->param('pass'); $request->repassword = $request->param('repass'); break; // 默認接口或者不存在的場景返回 default: break; } return $request; } }
至此一個簡單的中間件檢測工作完成,當然,這種寫法是由固定要求的 比如在多個控制訪問中,接口的統一帶上api 請求的統一帶上request這樣不管怎么樣都可以正常使用
單獨要說的兩個問題,就是其實可以將配置中需要用到的內容繼續進行
第一個問題是 中間件并不是萬能的,只能做一些請求處理,而且是必須帶參的,千萬不要去做不符合要求的高級驗證,這里最多的只是做一些前置驗證,讓數據安全或者讓數據飽滿
第二給問題是 不要在中間件中嘗試做不合時宜的動作,不要在中間件中執行超級復雜的代碼,如果你拿中間件做超級復雜的代碼或者超長運算,我估計可以坑死很多人,這里所說包括了盡量少使用自己函數庫定義的函數代碼驗證 有些避不開的還是可以使用的,比如密碼加密這種類似的代碼
推薦學習:《最新的10個thinkphp視頻教程》