这篇文章主要介绍了关于Laravel核心解读Response,有着一定的参考价值,现在分享给大家,有需要的朋友可以参考一下
Response
前面两节我们分别讲了Laravel的控制器和Request对象,在讲Request对象的那一节我们看了Request对象是如何被创建出来的以及它支持的方法都定义在哪里,讲控制器时我们详细地描述了如何找到Request对应的控制器方法然后执行处理程序的,本节我们就来说剩下的那一部分,控制器方法的执行结果是如何被转换成响应对象Response然后返回给客户端的。
创建Response
让我们回到Laravel执行路由处理程序返回响应的代码块:
namespace Illuminate\Routing;class Router implements RegistrarContract, BindingRegistrar{ 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) ); } protected function runRouteWithinStack(Route $route, Request $request) { $shouldSkipMiddleware = $this->container->bound('middleware.disable') && $this->container->make('middleware.disable') === true; //收集路由和控制器里应用的中间件 $middleware = $shouldSkipMiddleware ? [] : $this->gatherRouteMiddleware($route); return (new Pipeline($this->container)) ->send($request) ->through($middleware) ->then(function ($request) use ($route) { return $this->prepareResponse( $request,<b style="color:transparent">本文来源gao@!dai!ma.com搞$$代^@码!网!</b><strong>搞gaodaima代码</strong> $route->run() ); }); }}
在讲控制器的那一节里我们已经提到过runRouteWithinStack
方法里是最终执行路由处理程序(控制器方法或者闭包处理程序)的地方,通过上面的代码我们也可以看到执行的结果会传递给Router
的prepareResponse
方法,当程序流返回到runRoute
里后又执行了一次prepareResponse
方法得到了要返回给客户端的Response对象, 下面我们就来详细看一下prepareResponse
方法。
class Router implements RegistrarContract, BindingRegistrar{ /** * 通过给定值创建Response对象 * * @param \Symfony\Component\HttpFoundation\Request $request * @param mixed $response * @return \Illuminate\Http\Response|\Illuminate\Http\JsonResponse */ 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); }}