ThinkPHP5.1中間件在控制器中使用過程

ThinkPHP5.1中間件在控制器中使用過程

使用中間件的開始以及個人步驟描述,但願能夠幫到才學php 或者才學think框架的大家但願可以與大家交流,讓本身進步。

  1. 中間件在Thinkphp框架中的做用我已經明白了,就是在請求即將達到應用層以前,對用戶訪問資源時候,產生的header頭 或者 用戶的請求參數時候輸入的post 或get 或者別的請求類型,以及url 路徑進行操做,其中包括了前置或者後置操做或者執行順序等方案。在理解後以爲這個東西在處理用戶請求數據的時候有極大的做用,比之直接在控制器或者在行爲裏面處理好了不少。(因而懷着滿滿的激動心情閱讀5.1的文檔手冊)。
  2. 在閱讀完文檔後,按照官方手冊的方法,在命令行中敲出以下代碼:
    php think make:middleware Check
    這段代碼的意思沒有任何問題就是生產一箇中間件目錄以及建立一個新的名字爲Check中間件文件
    該內容正常完成沒有問題
  3. 按照文檔要求方案粘貼了5.1的文檔代碼clipboard.png徹底照着手冊複製的,沒有任何問題,確認進行了保存以及任何錯誤。
  4. 在此確認在個人admin模塊根目錄下放置了一個名字爲 middleware.php的文件 以下圖所示clipboard.png,就這樣進行一個註冊,那麼這個模塊下若是想使用中間件,就可使用了。
  5. 而後我在控制器內按照文檔手冊中的內容,根據控制器中間件內容描述加入瞭如圖所示的代碼clipboard.png,
  6. 結果發現,代碼沒有被執行,納悶的我摸了摸腦殼,按照個人理解應,若是這麼作了的話,應該能夠直接應用了纔對的,結果對象是個空的。無奈下,按照本身的理解,我在中間件內中止了代碼clipboard.pngclipboard.png
  7. 在看到本身但願看到的內容後,再次測試個人$request。 看到了我期待已久的東西,個人中間件好了clipboard.pngclipboard.png

至此以上步驟告訴我,第一步已經完成,我如今可使用一箇中間件作我想作的事情了

第一步 先吧名字變成我想變得 這裏有三處改動的地方。
clipboard.png
clipboard.png
clipboard.pngphp

再次刷新後發現依然可使用,絕對溜溜的跑起來。在這一步中,也堅決了個人一些使用想法,好比創造多箇中間件,每一個控制器都應該有一個相對應的,在這裏執行一些本身象處理的,在看到手冊上還可使用各類其餘的方法,包括執行順序的改變,這讓我心中各類意淫。今後代碼變得又能夠稍微高大上一點了。json

第二步 創建功能規則 配合Config配置中的自建文件,對訪問進行控制api

clipboard.png
clipboard.png
clipboard.png
clipboard.png

<?php
namespace apphttpmiddleware;
use thinkfacadeConfig;
use thinkfacadeRequest;
/**php框架

  • 登錄接口通用數據配置檢測

*/
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;
}

}app

至此一個簡單的中間件檢測工做完成,固然,這種寫法是由固定要求的 好比在多個控制訪問中,接口的統一帶上api 請求的統一帶上request這樣無論怎麼樣均可以正常使用

單獨要說的兩個問題,就是其實能夠將配置中須要用到的內容繼續進行

第一個問題是 中間件並非萬能的,只能作一些請求處理,並且是必須帶參的,千萬不要去作不符合要求的高級驗證,這裏最多的只是作一些前置驗證,讓數據安全或者讓數據飽滿框架

第二給問題是 不要在中間件中嘗試作不合時宜的動做,不要在中間件中執行超級複雜的代碼,若是你拿中間件作超級複雜的代碼或者超長運算,我估計能夠坑死不少人,這裏所說包括了儘可能少使用本身函數庫定義的函數代碼驗證 有些避不開的仍是可使用的,好比密碼加密這種相似的代碼函數

相關文章
相關標籤/搜索