国产av日韩一区二区三区精品,成人性爱视频在线观看,国产,欧美,日韩,一区,www.成色av久久成人,2222eeee成人天堂

Home php教程 PHP開發(fā) Detailed explanation of Laravel middleware implementation principle

Detailed explanation of Laravel middleware implementation principle

Dec 27, 2016 am 11:38 AM
laravel middleware

The examples in this article describe the implementation principles of Laravel's middleware. Share it with everyone for your reference, the details are as follows:

#1 What is middleware?

For a web application, before a request is actually processed, we may make various judgments on the request before it can be passed to a deeper level. And if we use if else like this, once more and more conditions need to be judged, it will make the code more difficult to maintain, and the coupling between systems will increase, and middleware can solve this problem. We can separate these judgments into middleware, which can easily filter requests.

#2 Middleware in Laravel

In Laravel, the implementation of middleware actually relies on the implementation of the IlluminatePipelinePipeline class. Let's first take a look at the code that triggers the middleware. It's very simple, just transfer the request to a closure after processing and then continue passing it on.

public function handle($request, Closure $next) {
  //do something for $request
  return $next($request);
}

#3 Internal implementation of middleware

As mentioned above, middleware is implemented by Pipeline, and its call is in IlluminateRoutingRouter

return (new Pipeline($this->container))
            ->send($request)
            ->through($middleware)
            ->then(function ($request) use ($route) {
              return $this->prepareResponse(
                $request,
                $route->run($request)
              );
            });

As you can see, the middleware execution process calls three methods. Let’s take a look at the codes of these three methods:

send method

public function send($passable){
  $this->passable = $passable;
  return $this;
}

In fact, the send method doesn’t do anything, it just sets the required The object of pipeline processing in middleware is the HTTP request instance here.

through method

public function through($pipes){
  $this->pipes = is_array($pipes) ? $pipes : func_get_args();
  return $this;
}

The through method is also very simple, which is to set the middleware processing that needs to be processed.

then method

Here comes the really difficult part. The then method code is very concise, but it is not easy to understand.

public function then(Closure $destination){
  //then方法接受一個(gè)閉包作為參數(shù),然后經(jīng)過getInitialSlice包裝,而getInitialSlice返回的其實(shí)也是一個(gè)閉包,如果還不知道什么是閉包先去看PHP文檔
  $firstSlice = $this->getInitialSlice($destination);
  //反轉(zhuǎn)中間件數(shù)組,主要是利用了棧的特性,用處接下來再說
  $pipes = array_reverse($this->pipes);
  //這個(gè)call_user_func先不要看,它其實(shí)就是執(zhí)行了一個(gè)array_reduce返回的閉包
  return call_user_func( 
    //接下來用array_reduce來用回調(diào)函數(shù)處理數(shù)組,建議先去PHP文檔讀懂a(chǎn)rray_reduce的執(zhí)行原理。其實(shí)arrary_reduce什么事情都沒干,就是包裝閉包然后移交給call_user_func來執(zhí)行
    array_reduce($pipes, $this->getSlice(), $firstSlice), $this->passable
  );
}

Then there is no more, so all the middleware is passed. Isn’t it very elegant?

Since the second parameter of aray_reduce requires a function, let’s focus on the source code of the getSlice() method

protected function getSlice(){
    return function ($stack, $pipe) {  //這里$stack
      return function ($passable) use ($stack, $pipe) {
        if ($pipe instanceof Closure) {
          return call_user_func($pipe, $passable, $stack);
        } else {
          list($name, $parameters) = $this->parsePipeString($pipe);
          return call_user_func_array([$this->container->make($name), $this->method],
          array_merge([$passable, $stack], $parameters));
        }
      };
    };
}

See the possibility It will be very dizzy, closure returns closure. To simplify it, getSlice() returns a function A, and function A returns function B. Why return two functions? Because we use $next($request) to pass the object during the transfer process, and $next($request) means that the closure is executed. This closure is function A, and then returns function B. , which can be passed to the next middleware.

Let’s simplify the code again:

//這里的$stack其實(shí)就是閉包,第一次遍歷的時(shí)候會(huì)傳入$firstSlice這個(gè)閉包,以后每次都會(huì)傳入下面的那個(gè)function; 而$pipe就是每一個(gè)中間件
array_reduce($pipes, function ($stack, $pipe) { 
  return function ($passable) use ($stack, $pipe) {
  };
}, $firstSlice);

Let’s look at this code again:

//判斷是否為閉包,這里就是判斷中間件形式是不是閉包,是的話直接執(zhí)行并且傳入$passable[請(qǐng)求實(shí)例]和$stack[傳遞給下一個(gè)中間件的閉包],并且返回
if ($pipe instanceof Closure) { 
  return call_user_func($pipe, $passable, $stack);
//不是閉包的時(shí)候就是形如這樣Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode執(zhí)行
} else { 
  //解析,把名稱返回,這個(gè)$parameters看了許久源碼還是看不懂,應(yīng)該是和參數(shù)相關(guān),不過不影響我們的分析
  list($name, $parameters) = $this->parsePipeString($pipe);
  //從容器中解析出中間件實(shí)例并且執(zhí)行handle方法
  return call_user_func_array([$this->container->make($name), $this->method],
  //$passable就是請(qǐng)求實(shí)例,而$stack就是傳遞的閉包
  array_merge([$passable, $stack], $parameters)); 
}

Look at another picture:

Detailed explanation of Laravel middleware implementation principle

Each iteration passes in the previous closure and the middleware that needs to be executed. Since the array is reversed, Based on the first-in-last-out feature of the stack, middleware 3 is packaged first, and middleware 1 is the outermost layer. Remember, array_reduce does not execute middleware code, but wraps middleware.

You should understand after seeing this, array_reduce will eventually return func3, then call_user_func(func3,$this->passable) is actually

return call_user_func($middleware[0]->handle, $this->passable, func2);

and the handle code in our middleware is :

public function handle($request, Closure $next) {
  return $next($request);
}

This is equivalent to return func2($request). The $request here is processed by the previous middleware. So the process of Zhengguo middleware is over, and it will be a bit confusing to understand. Just remember that the outermost call_user_func executes the middleware code in the end. I hope this article will be helpful to everyone's PHP program design based on the Laravel framework. helped.

For more detailed explanations of Laravel middleware implementation principles and related articles, please pay attention to the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undress AI Tool

Undress AI Tool

Undress images for free

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Clothoff.io

Clothoff.io

AI clothes remover

Video Face Swap

Video Face Swap

Swap faces in any video effortlessly with our completely free AI face swap tool!

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)