1、问题描述
在我们输入后台的ip或者域名的时候,浏览器展示给我们的url如下:
/index.php?r=site%2Flogin
但是很显然,SiteController
控制器下的默认动作是index
,因此这里就产生了两个问题:
- Yii是如何在运行
web/index.php
后知道要去访问site/index
的? - 访问
site/index
后,怎么跳转到site/login
页面的?
本文主要围绕这两个问题进行讲解。
2、应用主体
Yii中一个很重要的概念就是应用主体,Yii在创建应用主体的时候有个属性为[KaTeX parse error: Expected 'EOF', got '#' at position 71: …web-application#̲defaultRoute-detail)指定了默认要访问的控制器,其定义在yii\web\Application中,我们来看一下web/index.php
的代码:
<?php
... ...
(new yii\web\Application($config))->run();
大家可以看到,最后一行代码是创建了一个yii\web\Application的实例,因此Yii会按照实例里配置的[KaTeX parse error: Expected 'EOF', got '#' at position 71: …web-application#̲defaultRoute-detail)来将请求发送到相对应的控制器。
那如何改变默认的路由呢?
大家可以在$config
中去修改默认的路由配置,比如说在config/main-local.php
中修改:
<?php
$config = [
... ...
'defaultRoute' => "site1"
];
... ...
3、默认动作
默认的动作是在\yii\base\Controller
中定义的,属性名称为:$defaultAction
,从代码中得知,默认的值如下:
public $defaultAction = 'index';
到这里为止,大家应该知道为什么Yii在url中没有注明任何路由信息的时候会把请求发送到site/index
了,至于要改变这个规则,只需要修改默认的属性值就可以。
4、访问控制
接下来,我们讨论一下为什么在未登录的情况下会跳转到site/login
,要知道在site/index
中并没有跳转的代码:
class SiteController extends Controller
{
... ...
public function actionIndex()
{
return $this->render('index');
}
... ...
}
那它怎么获得用户登录的信息,并把未登录的请求转发到site/login
呢?大家注意,在如下代码中使用了权限控制:
class SiteController extends Controller
{
/**
* {@inheritdoc}
*/
public function behaviors()
{
return [
'access' => [
'class' => AccessControl::className(),
'rules' => [
... ...
//允许授权的用户访问login,index动作
[
'actions' => ['logout', 'index'],
'allow' => true,
'roles' => ['@'],
],
],
],
... ...
];
}
... ...
}
也就是说site/index
是需要用户登录后才可以访问的,判断访问权限的代码在上述指定的AccessControl
类中:
class AccessControl extends ActionFilter
{
protected function denyAccess($user)
{
if ($user !== false && $user->getIsGuest()) {
$user->loginRequired();
} else {
throw new ForbiddenHttpException(Yii::t('yii', 'You are not allowed to perform this action.'));
}
}
... ...
}
当用户未登录时,会调用denyAccess()
方法,这个方法会调用$user->loginRequired()
来执行接下来的跳转任务:
public function loginRequired($checkAjax = true, $checkAcceptHeader = true)
{
...
return Yii::$app->getResponse()->redirect($this->loginUrl);
...
}
也就是说跳转的目的地是$this->loginUrl
的值,我们看一下它的值是什么:
public $loginUrl = ['site/login'];
大家可以看到,其值是site/login
,到此大家应该可以理解为什么在未登录的情况下会跳转到site/login
页面了。
关注我的微信公众号,更多文章推送不遗漏