跟隨上節的腳步繼續研讀代碼。上節查看到了Slim/Router類的map方法。這節讓我們根據一個請求的執行過程具體學習下這個路由的核心類。
/**
* 增加一個路由
* Add route
*
* @param string[] $methods Array of HTTP methods
* @param string $pattern The route pattern
* @param callable $handler The route callable
*
* @return RouteInterface
*
* @throws InvalidArgumentException if the route pattern isn't a string
*/
public function map($methods, $pattern, $handler)
{
// 路由pattern必須是字符串
if (!is_string($pattern)) {
throw new InvalidArgumentException('Route pattern must be a string');
}
// Prepend parent group pattern(s)
// 前綴父組
if ($this->routeGroups) {
$pattern = $this->processGroups() . $pattern;
}
// 將請求方法變爲大寫
// According to RFC methods are defined in uppercase (See RFC 7231)
$methods = array_map("strtoupper", $methods);
// Add route
// 增加路由
$route = $this->createRoute($methods, $pattern, $handler);
$this->routes[$route->getIdentifier()] = $route;
$this->routeCounter++;
return $route;
}
若有路由前綴會加上前綴,下面看下createRoute,該方法創建了$router對象,也是我們get()方法返回的對象。
/**
* 創建一個新的路由對象
* Create a new Route object
*
* @param string[] $methods Array of HTTP methods
* @param string $pattern The route pattern
* @param callable $callable The route callable
*
* @return \Slim\Interfaces\RouteInterface
*/
protected function createRoute($methods, $pattern, $callable)
{
$route = new Route($methods, $pattern, $callable, $this->routeGroups, $this->routeCounter);
if (!empty($this->container)) {
$route->setContainer($this->container);
}
return $route;
}
該方法返回Route類對象$route。
/**
* 創建新的路由
* Create new route
*
* @param string|string[] $methods The route HTTP methods
* @param string $pattern The route pattern
* @param callable $callable The route callable
* @param RouteGroup[] $groups The parent route groups
* @param int $identifier The route identifier
*/
public function __construct($methods, $pattern, $callable, $groups = [], $identifier = 0)
{
$this->methods = is_string($methods) ? [$methods] : $methods;
$this->pattern = $pattern;
$this->callable = $callable;
$this->groups = $groups;
$this->identifier = 'route' . $identifier;
}
大致瞭解後,讓我們繼續回到index.php中,查看路由執行過程。由上可知,$app->get('/',function(){...});執行之後,返回了$route對象,該對象根據$methons請求方法,$pattern請求模式,$callable請求內容進行一系列的處理。但只是並未完成一個完成的生命週期,請求和響應都還在$app對象中,隱而不發,待$app->run()執行之後,才能返回響應,完成一個完整的生命週期。