在yii2源码(1)--执行流程 中提到,在\yii\web\Application.php文件中有一下代码:
public function handleRequest($request)
{
if (empty($this->catchAll)) {
list ($route, $params) = $request->resolve();//取出路由及参数,下节再具体分析(调用了urlManager组件)
} else {
$route = $this->catchAll[0];
$params = $this->catchAll;
unset($params[0]);
}
try {
Yii::trace("Route requested: '$route'", __METHOD__);
$this->requestedRoute = $route;
$result = $this->runAction($route, $params);//运行控制器中的Acition,下面有详细介绍
if ($result instanceof Response) {
return $result;
} else {
$response = $this->getResponse();
/*这个是加载yii\base\Response类,在外部可以Yii::$app->get('response')、Yii::$app->getResponse()、Yii::$app->response 等等方式来加载response类,主要用来加载http状态,及头信息,如301,302,404,ajax头等等的获取*/
if ($result !== null) {
$response->data = $result;
}
return $response;
}
} catch (InvalidRouteException $e) {
throw new NotFoundHttpException(Yii::t('yii', 'Page not found.'), $e->getCode(), $e);
}
}
$request->resolve()方法调用并加载了urlManager组件,这节分析urlManager组件的加载和运行
在yii2/web/Request.php文件中:
public function resolve()
{
$result = Yii::$app->getUrlManager()->parseRequest($this); // 获得UrlManager对象,并处理request,获得路由和参数
if ($result !== false) {
list ($route, $params) = $result;
if ($this->_queryParams === null) {
$_GET = $params + $_GET; // preserve numeric keys
} else {
$this->_queryParams = $params + $this->_queryParams;
}
return [$route, $this->getQueryParams()];
} else {
throw new NotFoundHttpException(Yii::t('yii', 'Page not found.'));
}
}
Yii::$app->getUrlManager()方法返回了yii\web\UrlManager对象,然后parseRequest($this); 调用了yii2/web/UrlManager.php文件的 parseRequest方法:
public function parseRequest($request)
{
if ($this->enablePrettyUrl) {
/* @var $rule UrlRule */
foreach ($this->rules as $rule) {
$result = $rule->parseRequest($this, $request);
if (YII_DEBUG) {
Yii::trace([
'rule' => method_exists($rule, '__toString') ? $rule->__toString() : get_class($rule),
'match' => $result !== false,
'parent' => null
], __METHOD__);
}
if ($result !== false) {
return $result;
}
}
if ($this->enableStrictParsing) {
return false;
}
Yii::trace('No matching URL rules. Using default URL parsing logic.', __METHOD__);
$suffix = (string) $this->suffix;
$pathInfo = $request->getPathInfo();
$normalized = false;
if ($this->normalizer !== false) {
$pathInfo = $this->normalizer->normalizePathInfo($pathInfo, $suffix, $normalized);
}
if ($suffix !== '' && $pathInfo !== '') {
$n = strlen($this->suffix);
if (substr_compare($pathInfo, $this->suffix, -$n, $n) === 0) {
$pathInfo = substr($pathInfo, 0, -$n);
if ($pathInfo === '') {
// suffix alone is not allowed
return false;
}
} else {
// suffix doesn't match
return false;
}
}
if ($normalized) {
// pathInfo was changed by normalizer - we need also normalize route
return $this->normalizer->normalizeRoute([$pathInfo, []]);
} else {
return [$pathInfo, []];
}
} else {
Yii::trace('Pretty URL not enabled. Using default URL parsing logic.', __METHOD__);
$route = $request->getQueryParam($this->routeParam, '');
if (is_array($route)) {
$route = '';
}
return [(string) $route, []];
}
}