国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

Laravel 中間件

zebrayoung / 999人閱讀

摘要:至此,返回本次請求的響應。最內層即路由分發,解析請求,返回響應的操作代碼展示,后續分析即執行匿名函數,位于下面方法中。

Laravel 中間件 代碼展示
protected function sendRequestThroughRouter($request)
{
    # $this->app->instance("request", $request);

    # Facade::clearResolvedInstance("request");

    # $this->bootstrap();

    return (new Pipeline($this->app))
                ->send($request)
                ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)
                ->then($this->dispatchToRouter());      // $this->dispatchToRouter(),后期繼續
}

new IlluminateRoutingPipeline($this->app):
public function __construct(Container $container = null)
{
    $this->container = $container;
}
public function send($passable)
{
    $this->passable = $passable;

    return $this;
}
public function through($pipes)
{
    ####################################################################################
    #    $this->middleware = [                                                         #
    #        IlluminateFoundationHttpMiddlewareCheckForMaintenanceMode::class,    #
    #        IlluminateFoundationHttpMiddlewareValidatePostSize::class,           #
    #        AppHttpMiddlewareTrimStrings::class,                                  #
    #        IlluminateFoundationHttpMiddlewareConvertEmptyStringsToNull::class,  #
    #    ];                                                                            #
    ####################################################################################
    $this->pipes = is_array($pipes) ? $pipes : func_get_args();

    return $this;
}
// 中間件的本質
public function then(Closure $destination)
{
    $pipeline = array_reduce(
        array_reverse($this->pipes), $this->carry(), $this->prepareDestination($destination)
    );
    // 上面操作完之后返回一個匿名函數,接受一個參數
    return $pipeline($this->passable);
}
// 注意這個是子類里面會調用的父carry,區別在于子類加入了異常處理
protected function carry()
{
    // 接受匿名函數$stack參數和$pipe參數,返回匿名函數,再將此匿名函數作為第一個參數$stack迭代傳入。
    return function ($stack, $pipe) {
        return function ($passable) use ($stack, $pipe) {
            if ($pipe instanceof Closure) {
                return $pipe($passable, $stack);
            } elseif (! is_object($pipe)) {
                list($name, $parameters) = $this->parsePipeString($pipe);

                $pipe = $this->getContainer()->make($name);

                $parameters = array_merge([$passable, $stack], $parameters);
            } else {
                $parameters = [$passable, $stack];
            }
            // 中間件作用是提供了一種方便的機制來過濾進入應用的 HTTP 請求
            // $this->method默認為handle,可通過via方法進行設置
            return $pipe->{$this->method}(...$parameters);
        };
    };
}
protected function parsePipeString($pipe)
{
    // 不帶參數的pipe(class)或帶參數(參數以,分割)的pipe(class:param1,param2,param3...)
    list($name, $parameters) = array_pad(explode(":", $pipe, 2), 2, []);

    if (is_string($parameters)) {
        $parameters = explode(",", $parameters);
    }
    // $parameters為[]數組或[param1,param2,param3...]
    return [$name, $parameters];
}
protected function prepareDestination(Closure $destination)
{
    return function ($passable) use ($destination) {
        return $destination($passable);
    };
}

前置條件

array_reduce接受三個參數,第一個參數接收數組,第二個參數函數名(也可以是匿名函數,函數有兩個參數,分別代表$result和$item),第三個參數(可選),該參數將被當成是數組中的第一個值來處理,或者如果數組為空的話就作為最終返回值。

匿名函數也叫閉包函數(closures),允許臨時創建一個沒有指定名稱的函數,通過 Closure 類來實現的。

當對閉包函數進行賦值時,PHP 便會自動將此種表達式轉換成內置類 Closure 的對象對象在進行賦值。

當閉包函數使用到 use 使用外部數據時,會在 Closure 對象生成一個 static 屬性數組進行存放。

當閉包函數使用到參數時,會在 Closure 對象生成一個 parameter 屬性數組進行存放。

    public function then(Closure $destination)
    {
        $pipeline = array_reduce(
            array_reverse($this->pipes), $this->carry(), $this->prepareDestination($destination)
        );
        return $pipeline($this->passable);
    }

生成最終匿名函數的過程:

    array_reduce執行第一次時得到如下簡化的匿名函數返回,將會繼續作為第一個參數進行迭代:        
        object(Closure)#id (1) {
          ["static"]=>
          array(2) {
            ["stack"]=>
            object(Closure)#1 (0) { // $this->prepareDestination($destination)
            }
            ["pipe"]=>
            string(15) "IlluminateFoundationHttpMiddlewareConvertEmptyStringsToNull"
          }
        }
    第二次:
        object(Closure)#id (1) {
          ["static"]=>
          array(2) {
            ["stack"]=>
            object(Closure)#id (1) {
              ["static"]=>
              array(2) {
                ["stack"]=>
                object(Closure)#1 (0) { // $this->prepareDestination($destination)
                }
                ["pipe"]=>
                string(15) "IlluminateFoundationHttpMiddlewareConvertEmptyStringsToNull"
              }
            }
            ["pipe"]=>
            string(15) "AppHttpMiddlewareTrimStrings"
          }
        }
    第三次:
        object(Closure)#id (1) {
          ["static"]=>
          array(2) {
            ["stack"]=>
            object(Closure)#id (1) {
              ["static"]=>
              array(2) {
                ["stack"]=>
                object(Closure)#id (1) {
                  ["static"]=>
                  array(2) {
                    ["stack"]=>
                    object(Closure)#1 (0) { // $this->prepareDestination($destination)
                    }
                    ["pipe"]=>
                    string(15) "IlluminateFoundationHttpMiddlewareConvertEmptyStringsToNull"
                  }
                }
                ["pipe"]=>
                string(15) "AppHttpMiddlewareTrimStrings"
              }
            }
            ["pipe"]=>
            string(15) "IlluminateFoundationHttpMiddlewareValidatePostSize"
          }
        }

依次類推,最終得到一個匿名函數如下(接受一個參數,此匿名函數內部使用上面遞歸形式的$pipe和$stack)。

    function ($passable) {
        if ($pipe instanceof Closure) {
            return $pipe($passable, $stack);
        } elseif (! is_object($pipe)) {
            list($name, $parameters) = $this->parsePipeString($pipe);

            $pipe = $this->getContainer()->make($name); // 實例化middleware

            $parameters = array_merge([$passable, $stack], $parameters);
        } else {
            $parameters = [$passable, $stack];
        }
        return $pipe->{$this->method}(...$parameters);  // 語法糖模式,因為middleware參數可有可無
    };

最終匿名函數的調用過程(從最外層開始,這就是前面為什么要array_reverse,一層一層往里撥,整體上的處理是:$pipe若是匿名函數,直接調用。若是字符串,則解析成對應的類和參數,make類,再組成參數數組。最后調用$pipe->handle)

    最外層($pipe=IlluminateFoundationHttpMiddlewareCheckForMaintenanceMode):
    (new IlluminateFoundationHttpMiddlewareCheckForMaintenanceMode)->handle($passable, $stack)
    執行完前置操作后,調用$stack($passable),繼續進行下一層

    下一層($pipe=IlluminateFoundationHttpMiddlewareValidatePostSize):
    (new IlluminateFoundationHttpMiddlewareValidatePostSize)->handle($passable, $stack)
    執行完前置操作后,調用$stack($passable),繼續進行下一層

    **以此類推,當每層中間件的前置任務全部完成,即遞歸執行到最里面一層(路由分發,解析請求,返回響
    應),再由最內層一層一層往回走,執行每層中間件的后置任務。至此,返回本次請求的響應。**
    

最內層(即路由分發,解析請求,返回響應)的操作代碼展示,后續分析:即執行$destination($passable)匿名函數,位于下面方法中。

    
    protected function prepareDestination(Closure $destination)
    {
        return function ($passable) use ($destination) {
            return $destination($passable);
        };
    }
    $destination:
    protected function dispatchToRouter()
    {
        return function ($request) {
            $this->app->instance("request", $request);

            return $this->router->dispatch($request);
        };
    }
    

說明:
所有的后置操作,都是執行到最內層,遞歸往回走時才會執行逐層執行。

文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。

轉載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/22602.html

相關文章

  • Laravel思維導圖之Laravel HTTP路由、間件、控制器

    摘要:又限于層的內容太多,我在這篇中將整理路由中間件控制器部分內容。前者定義頁面路由,默認應用中間件組后者定義無狀態路由,會應用中間件組。命名路由可以為指定路由或者控制器方法命名,也可以為已命名的路由生成。 showImg(https://segmentfault.com/img/remote/1460000010882838); 上圖列出了 Laravel HTTP 層的相關知識大綱。由于...

    linkin 評論0 收藏0
  • 「新輪子」PHP CORS (Cross-origin resource sharing),解決 P

    摘要:而我的新輪子也并不是專門解決它的問題的,而是順便解決而已。概述這個包,支持在所有的項目中使用。一旦出現成員,代表允許全部。列出允許跨域請求的方法列表,默認是代表所有方法。信息地址嗯,新輪子,求一波。 showImg(https://segmentfault.com/img/bV5VxN?w=844&h=656); 是的,可能了解 Laravel 的都知道,在 Laravel 中簡單的設...

    lbool 評論0 收藏0
  • 深入理解Laravel間件

    摘要:中的中間件是中的一個重點本篇將從源碼的角度去講解中的中間件洞察中的中間件是如何運行的明白為何我們使用中間件的時候要進行那些步驟本篇文章假設讀者已經掌握中間件的基本用法如果不了解其用法可以移步查看中間件的使用我們都知道使用中間件有三個步驟使用 Laravel中的中間件是laravel中的一個重點,本篇將從源碼的角度去講解Lravel中的中間件,洞察Laravel中的中間件是如何運行的,明...

    xiaotianyi 評論0 收藏0
  • Laravel間件原理

    摘要:直到所有中間件都執行完畢,最后在執行最后的即上述的方法如果上述有地方難懂的,可以參考這邊文章內置函數在中的使用以上是在通過全局中間件時的大致流程,通過中間件和路由中間件也是一樣的,都是采用管道流操作,詳情可翻閱源碼 簡介 Laravel 中間件提供了一種方便的機制來過濾進入應用的 HTTP 請求, 如ValidatePostSize用來驗證POST請求體大小、ThrottleReque...

    張憲坤 評論0 收藏0
  • 【日常填坑】之ajax請求laravel的api接口

    摘要:合適和夠用是最完美的追求。比如從頁面去請求的資源。它允許瀏覽器向跨源服務器,發出請求,從而克服了只能同源使用的限制。定義在中的路由都是無狀態的,并且會應用中間件組。 關于作者 程序開發人員,不拘泥于語言與技術,目前主要從事PHP和前端開發,使用Laravel和VueJs,App端使用Apicloud混合式開發。合適和夠用是最完美的追求。 個人網站:http://www.linganm...

    Arno 評論0 收藏0
  • 【日常填坑】之ajax請求laravel的api接口

    摘要:合適和夠用是最完美的追求。比如從頁面去請求的資源。它允許瀏覽器向跨源服務器,發出請求,從而克服了只能同源使用的限制。定義在中的路由都是無狀態的,并且會應用中間件組。 關于作者 程序開發人員,不拘泥于語言與技術,目前主要從事PHP和前端開發,使用Laravel和VueJs,App端使用Apicloud混合式開發。合適和夠用是最完美的追求。 個人網站:http://www.linganm...

    neu 評論0 收藏0

發表評論

0條評論

最新活動
閱讀需要支付1元查看
<