接着昨天的内容,继续学习Router类的方法
先看一下 dispatch 方法
/**
* 给http请求发送路由
* Dispatch router for HTTP request
*
* @param ServerRequestInterface $request The current HTTP request object
* 返回的是一个数组
* @return array
*
* @link https://github.com/nikic/FastRoute/blob/master/src/Dispatcher.php
*/
public function dispatch(ServerRequestInterface $request)
{
$uri = '/' . ltrim($request->getUri()->getPath(), '/');
return $this->createDispatcher()->dispatch(
$request->getMethod(),
$uri
);
}
紧接着,我们看一下 createDispatcher 方法
createDispatcher
/**
* 这里返回了 \FastRoute\Dispatcher类
* @return \FastRoute\Dispatcher
*/
protected function createDispatcher()
{
if ($this->dispatcher) {
return $this->dispatcher;
}
$routeDefinitionCallback = function (RouteCollector $r) {
foreach ($this->getRoutes() as $route) {
$r->addRoute($route->getMethods(), $route->getPattern(), $route->getIdentifier());
}
};
if ($this->cacheFile) {
$this->dispatcher = \FastRoute\cachedDispatcher($routeDefinitionCallback, [
'routeParser' => $this->routeParser,
'cacheFile' => $this->cacheFile,
]);
} else {
$this->dispatcher = \FastRoute\simpleDispatcher($routeDefinitionCallback, [
'routeParser' => $this->routeParser,
]);
}
return $this->dispatcher;
}
vendor/nikic/fast-route/src/Dispatcher/RegexBasedAbstract.php
该类实现了Dispatcher接口,并且实现了dispatch 方法,用来被调用
下面看下 relativePathFor 方法
/**
* 为一个路由构建路径,除了基本的路径之外
* Build the path for a named route excluding the base path
*
* @param string $name Route name
* @param array $data Named argument replacement data
* @param array $queryParams Optional query string parameters
*
* @return string
*
* @throws RuntimeException If named route does not exist
* @throws InvalidArgumentException If required data not provided
*/
public function relativePathFor($name, array $data = [], array $queryParams = [])
{
$route = $this->getNamedRoute($name);
$pattern = $route->getPattern();
$routeDatas = $this->routeParser->parse($pattern);
// $routeDatas is an array of all possible routes that can be made. There is
// one routedata for each optional parameter plus one for no optional parameters.
//
// The most specific is last, so we look for that first.
$routeDatas = array_reverse($routeDatas);
$segments = [];
foreach ($routeDatas as $routeData) {
foreach ($routeData as $item) {
if (is_string($item)) {
// this segment is a static string
$segments[] = $item;
continue;
}
// This segment has a parameter: first element is the name
if (!array_key_exists($item[0], $data)) {
// we don't have a data element for this segment: cancel
// testing this routeData item, so that we can try a less
// specific routeData item.
$segments = [];
$segmentName = $item[0];
break;
}
$segments[] = $data[$item[0]];
}
if (!empty($segments)) {
// we found all the parameters for this route data, no need to check
// less specific ones
break;
}
}
if (empty($segments)) {
throw new InvalidArgumentException('Missing data for URL segment: ' . $segmentName);
}
$url = implode('', $segments);
if ($queryParams) {
$url .= '?' . http_build_query($queryParams);
}
return $url;
}
这块儿没看太明白,明天继续