跟随上节的脚步继续研读代码。上节查看到了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()执行之后,才能返回响应,完成一个完整的生命周期。