博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
路由处理生成响应
阅读量:4598 次
发布时间:2019-06-09

本文共 9315 字,大约阅读时间需要 31 分钟。

index.php

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);//处理请求$response = $kernel->handle(    //请求实例的创建    $request = Illuminate\Http\Request::capture());

  

\vendor\laravel\framework\src\Illuminate\Foundation\Http\Kernel.php

/**     * Handle an incoming HTTP request.     *处理一个http请求     * @param  \Illuminate\Http\Request  $request     * @return \Illuminate\Http\Response     */    public function handle($request)    {        try {            //在请求过程中会添加CSRF保护,服务端会发送一个csrf令牌给客户端(cookie)            $request->enableHttpMethodParameterOverride();            //请求处理,通过路由传输请求实例            $response = $this->sendRequestThroughRouter($request);        } catch (Exception $e) {            $this->reportException($e);            $response = $this->renderException($request, $e);        } catch (Throwable $e) {            $this->reportException($e = new FatalThrowableError($e));            $response = $this->renderException($request, $e);        }        $this->app['events']->dispatch(            new Events\RequestHandled($request, $response)        );        return $response;    }

  

/**     * Send the given request through the middleware / router.     *     * @param  \Illuminate\Http\Request  $request     * @return \Illuminate\Http\Response     */    protected function sendRequestThroughRouter($request)    {        $this->app->instance('request', $request);        Facade::clearResolvedInstance('request');        //针对请求为应用程序'拔靴带' 执行bootstrap类的数组        //在请求处理阶段共有7个环节,每一个环节由一个类来实现的        //而且每个类都会有一个bootstrap()函数用于实现准备工作        $this->bootstrap();        return (new Pipeline($this->app))                    ->send($request)                    ->through($this->app->shouldSkipMiddleware() ? [] : $this->middleware)                    ->then($this->dispatchToRouter());    }

  

dispatchToRouter()

/**     * Get the route dispatcher callback.     *设置路由分发回调函数     * @return \Closure     */    protected function dispatchToRouter()    {        return function ($request) {            $this->app->instance('request', $request);            return $this->router->dispatch($request);        };    }

  

vendor\laravel\framework\src\Illuminate\Routing\Router.php

/**     * Dispatch the request to the application.     *     * @param  \Illuminate\Http\Request  $request     * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse     */    public function dispatch(Request $request)    {        $this->currentRequest = $request;        return $this->dispatchToRoute($request);    }

  

//分发请求到指定路由并返回一个响应

public function dispatchToRoute(Request $request)    {        return $this->runRoute($request, $this->findRoute($request));    }

  

protected function runRoute(Request $request, Route $route)    {        $request->setRouteResolver(function () use ($route) {            return $route;        });        $this->events->dispatch(new Events\RouteMatched($route, $request));        return $this->prepareResponse($request,            $this->runRouteWithinStack($route, $request)        );    }

  

//通过实例栈启动给定的路由

1     protected function runRouteWithinStack(Route $route, Request $request) 2     { 3         $shouldSkipMiddleware = $this->container->bound('middleware.disable') && 4                                 $this->container->make('middleware.disable') === true; 5  6         $middleware = $shouldSkipMiddleware ? [] : $this->gatherRouteMiddleware($route); 7  8         return (new Pipeline($this->container)) 9                         ->send($request)10                         ->through($middleware)11                         ->then(function ($request) use ($route) {12                             return $this->prepareResponse(13                                 $request, $route->run()14                             );15                         });16     }

 

在路由信息存储实例中,通过“ $route = Sthis -> findRoute ( $request ) ; ”来查找请求对应的路由实例,

查找主要是根据请求的方法和请求 URI 来实现对应,当查找到请求对应的路由后,请求将会传递到对应的路由中去处理

,即’ " $route-> run ( $ request ) "

 

vendor\laravel\framework\src\Illuminate\Routing\Route.php

执行路由动作并返回响应

1     public function run() 2     { 3         $this->container = $this->container ?: new Container; 4  5         try { 6             if ($this->isControllerAction()) { 7                 return $this->runController(); 8             } 9 10             return $this->runCallable();11         } catch (HttpResponseException $e) {12             return $e->getResponse();13         }14     }

//将请求发送到常规分发器去处理

1     protected function runController()2     {3         return $this->controllerDispatcher()->dispatch(4             $this, $this->getController(), $this->getControllerMethod()5         );6     }

在清求对应的路由中,会检测是否使用常规的控制分发器去处理,在初始的 Larave 框架中使用的是常规控制分发器,

通过服务容器自动生成这个控制分发器,这个服务是通过服务提供者 ControUerservicoProvider 注册的,下一步将会把请求及路由中关于处理函数的信息交给控制分发器去处理,

这里对路由中关于处理函数的信息是以控制器类名和函数名给出的,即$class和$method

 

控制器的生成:

控制器生成在控制分发器中,将会根据路由提供的响应函数信息来实例化控制器类,并调用对应的响应函数生成响应的内容部分厂.下面给出部分源码:

vendor\laravel\framework\src\Illuminate\Routing\ControllerDispatcher.php

向给定的控制器和方法发送请求。

1     public function dispatch(Route $route, $controller, $method) 2     { 3         $parameters = $this->resolveClassMethodDependencies( 4             $route->parametersWithoutNulls(), $controller, $method 5         ); 6  7         if (method_exists($controller, 'callAction')) { 8             return $controller->callAction($method, $parameters); 9         }10 11         return $controller->{
$method}(...array_values($parameters));12 }

 

响应的生成

\vendor\laravel\framework\src\Illuminate\Routing\Router.php

protected function runRoute(Request $request, Route $route)    {        $request->setRouteResolver(function () use ($route) {            return $route;        });        $this->events->dispatch(new Events\RouteMatched($route, $request));        return $this->prepareResponse($request,            $this->runRouteWithinStack($route, $request)        );    }

  

public function prepareResponse($request, $response)    {        return static::toResponse($request, $response);    }

  

public static function toResponse($request, $response)    {        if ($response instanceof Responsable) {            $response = $response->toResponse($request);        }        if ($response instanceof PsrResponseInterface) {            $response = (new HttpFoundationFactory)->createResponse($response);        } elseif (! $response instanceof SymfonyResponse &&                   ($response instanceof Arrayable ||                    $response instanceof Jsonable ||                    $response instanceof ArrayObject ||                    $response instanceof JsonSerializable ||                    is_array($response))) {            $response = new JsonResponse($response);        } elseif (! $response instanceof SymfonyResponse) {            $response = new Response($response);        }        if ($response->getStatusCode() === Response::HTTP_NOT_MODIFIED) {            $response->setNotModified();        }        return $response->prepare($request);    }

  

vendor\symfony\http-foundation\Response.php

在发送到客户端之前准备响应

1     public function prepare(Request $request) 2     { 3         $headers = $this->headers; 4  5         if ($this->isInformational() || $this->isEmpty()) { 6             $this->setContent(null); 7             $headers->remove('Content-Type'); 8             $headers->remove('Content-Length'); 9         } else {10             // Content-type based on the Request11             if (!$headers->has('Content-Type')) {12                 $format = $request->getRequestFormat();13                 if (null !== $format && $mimeType = $request->getMimeType($format)) {14                     $headers->set('Content-Type', $mimeType);15                 }16             }17 18             // Fix Content-Type19             $charset = $this->charset ?: 'UTF-8';20             if (!$headers->has('Content-Type')) {21                 $headers->set('Content-Type', 'text/html; charset='.$charset);22             } elseif (0 === stripos($headers->get('Content-Type'), 'text/') && false === stripos($headers->get('Content-Type'), 'charset')) {23                 // add the charset24                 $headers->set('Content-Type', $headers->get('Content-Type').'; charset='.$charset);25             }26 27             // Fix Content-Length28             if ($headers->has('Transfer-Encoding')) {29                 $headers->remove('Content-Length');30             }31 32             if ($request->isMethod('HEAD')) {33                 // cf. RFC2616 14.1334                 $length = $headers->get('Content-Length');35                 $this->setContent(null);36                 if ($length) {37                     $headers->set('Content-Length', $length);38                 }39             }40         }41 42         // Fix protocol43         if ('HTTP/1.0' != $request->server->get('SERVER_PROTOCOL')) {44             $this->setProtocolVersion('1.1');45         }46 47         // Check if we need to send extra expire info headers48         if ('1.0' == $this->getProtocolVersion() && false !== strpos($this->headers->get('Cache-Control'), 'no-cache')) {49             $this->headers->set('pragma', 'no-cache');50             $this->headers->set('expires', -1);51         }52 53         $this->ensureIEOverSSLCompatibility($request);54 55         return $this;56     }

 

转载于:https://www.cnblogs.com/sunlong88/p/9364679.html

你可能感兴趣的文章
计算机硬盘大小转换(B,KB,MB,GB,TB,PB之间的大小转换)
查看>>
10.2计数与概率基础
查看>>
ssh无密码登陆
查看>>
使用django book2.0 时候,输入python manage.py sqlall books 报错解决办法
查看>>
Linux中docker的使用
查看>>
编译器选项
查看>>
VirtualBox虚拟机磁盘瘦身
查看>>
CSS的三种样式
查看>>
关于hadoop集群的简单性能测试——mapreduce性能,hive性能,并行计算分析(原创)...
查看>>
Asp.Net 4中使用路由时使用SiteMap
查看>>
linux之软连接 硬链接
查看>>
javascript中数组与字符串之间的转换以及字符串的替换
查看>>
使用pip安装离线包
查看>>
ORACLE 统计查看每一个表的行数
查看>>
【bzoj4281】[ONTAK2015]Związek Harcerstwa Bajtockiego 树上倍增+LCA
查看>>
Otto开发初探——微服务依赖管理新利器
查看>>
移动端开发:架构那点事!
查看>>
flex lineChart 显示所有的数据节点
查看>>
BZOJ1609 [Usaco2008 Feb]Eating Together麻烦的聚餐
查看>>
ffmpeg静态库Windows版本
查看>>