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這樣不管怎麼樣都可以正常使用
單獨要說的兩個問題,就是其實可以將設定中需要用到的內容繼續進行
第一個問題是 中介軟體並不是萬能的,只能做一些請求處理,而且是必須帶參的,千萬不要去做不符合要求的高階驗證,這裡最多的只是做一些前置驗證,讓資料安全或者讓資料飽滿
第二給問題是 不要在中介軟體中嘗試做不合時宜的動作,不要在中介軟體中執行超級複雜的程式碼,如果你拿中介軟體做超級複雜的程式碼或者超長運算,我估計可以坑死很多人,這裡所說包括了儘量少使用自己函數庫定義的函數程式碼驗證 有些避不開的還是可以使用的,比如密碼加密這種類似的程式碼