iT邦幫忙

2024 iThome 鐵人賽

DAY 10
0
Modern Web

Laravel 那麼好用還需要自幹框架嗎系列 第 10

Day 10:runRoute() 實作

  • 分享至 

  • xImage
  •  

昨天我們看過了 $this->runRoute($request, $this->findRoute($request)); 這段裡面 findRoute() 的實作。

今天我們要來看看 runRoute() 的實作

/**
 * Return the response for the given route.
 *
 * @param  \Illuminate\Http\Request  $request
 * @param  \Illuminate\Routing\Route  $route
 * @return \Symfony\Component\HttpFoundation\Response
 */
protected function runRoute(Request $request, Route $route)
{
	$request->setRouteResolver(fn () => $route);

	$this->events->dispatch(new RouteMatched($route, $request));

	return $this->prepareResponse($request,
		$this->runRouteWithinStack($route, $request)
	);
}

這裡面 runRouteWithinStack()

/**
 * Run the given route within a Stack "onion" instance.
 *
 * @param  \Illuminate\Routing\Route  $route
 * @param  \Illuminate\Http\Request  $request
 * @return mixed
 */
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(fn ($request) => $this->prepareResponse(
						$request, $route->run()
					));
}

到這邊,我們終於看到最核心執行路由的函數 $route->run() 被呼叫的地方了。

之後我們看 run() 的實作

/**
 * Run the route action and return the response.
 *
 * @return mixed
 */
public function run()
{
	$this->container = $this->container ?: new Container;

	try {
		if ($this->isControllerAction()) {
			return $this->runController();
		}

		return $this->runCallable();
	} catch (HttpResponseException $e) {
		return $e->getResponse();
	}
}

這邊會將輸入的路由區分成 Controller 定義的,或者是用 Callable 結構定義的,類似這種方式的路由

Route::get('/greeting', function () {
    return 'Hello World';
});

今天我們要看的是 Controller 定義的,所以是看 $this->runController()

/**
 * Run the route action and return the response.
 *
 * @return mixed
 *
 * @throws \Symfony\Component\HttpKernel\Exception\NotFoundHttpException
 */
protected function runController()
{
	return $this->controllerDispatcher()->dispatch(
		$this, $this->getController(), $this->getControllerMethod()
	);
}

這邊的 dispatch() 實作則是

/**
 * Dispatch a request to a given controller and method.
 *
 * @param  \Illuminate\Routing\Route  $route
 * @param  mixed  $controller
 * @param  string  $method
 * @return mixed
 */
public function dispatch(Route $route, $controller, $method)
{
	$parameters = $this->resolveParameters($route, $controller, $method);

	if (method_exists($controller, 'callAction')) {
		return $controller->callAction($method, $parameters);
	}

	return $controller->{$method}(...array_values($parameters));
}

到這邊,我們終於看到 $controller->{$method}(...array_values($parameters)) 這段執行 Controller Action 的部分了,這也就是這段程式透過這麼多類別,最後實際要做的事情:讓正確的控制器執行正確的方法。

今天這段程式就看到這邊,我們明天見


上一篇
Day 09:findRoute() 實作、SymfonyRoute
下一篇
Day 11:試用 symfony/routing
系列文
Laravel 那麼好用還需要自幹框架嗎18
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言