一.问题
碰到个问题,http://local.wx.cntv.cn/auditset/admin/apply/test.html访问不到

二.心情
心情无比不好,我检查了各种配置,写了对比的mp路径的...等等吧.都不好使,我最终决定看下源码.
三.流程
(1).我是先看了一遍yii的文档.
a.yii的文档相当于需求,源码是对需求的实现.这样能好理解些.
b.自己的需求是否可以被满足
c.文档中多数会有一些实现逻辑.看源码时能轻松些
(2).熟悉yii实现的大体逻辑,根据报错简单确定下需要看的类(当然这个我是熟悉的)
a.报错类

是web\Application.php这个类报错.找找上下左右大概就能知道需要看什么了.
a.1 第一个类web\Application,先看类参考手册确定下,实现的什么功能,继承关系,有问题的方法都干了什么?

就是这个方法,接收一个request对象(请求信息),返回一个response对象(响应信息),中间就是请求的处理,其中有一步应该是路由解析.
a.2 look look这个方法的实现



(1)是为了处理请求诞生route(路由信息)和param参数,同时包括一个catchAll路由的实现
(2)是通过路由信息诞生action对象,处理参数

a.3 var_dump($route,$param)看看是什么东西?确定下报错的位置

说明根据request已经解析出来route和param了
那报错就是runAction中的问题了.在通过这个路由诞生action对象时有的问题.
a.4

解析一个路由信息,创建对应的module,controller,action实例,之后调用base\Controller的runAction运行action实例传给过来的param参数.
a5

应该是(1)报错了.is_array($parts)不是个数组,报错.
关注一下这个$id,我发现报错没有这个$id/$route 而是$route,那这个$id是个什么呢?

a6 $id是从getUniqueId来的,这个$this是web/Application实际使用的是base/Application的getUniqueId,必然返回''
a7 $route是auditset/admin/apply/index

a8 解析的逻辑是

先分成auditset admin apply index进入一个递归确认的过程
auditset控制器不存在
那么auditset需要是modules中的一个
admin是不是一个控制器,不是.
那么admin需要是auditset模块的子模块的一个.这明显是不成立的.那么就还有别的匹配规则.
因为http://local.wx.cntv.cn/auditset/mp/test/test?mpid=18 解析出来的是auditset/mp/test/test是合法的.有正则规则
a9 具体怎么实现的呢?

1是路由为空走默认路由
2.是//在路径中应该不合法无法解析,trim动作是为了递归时去掉头部的/,下面route进入递归的时候是没有头部的/的.

1.是否是最后一个id,通过是否还有/判断
是: $id = $route 这个id就是控制器映射的id
不是:那么分解路由,第一个/第二个.第一个是$id后面是路由
2.判断$id是否在controller映射中.在就返回了.希望中$controller确认了.后面是action;

1.$this->controllerMap在application为module时,我这个项目是空的.
2.那么去看是不是一个module auditset,是的话去但是controller.

在查看getModule时注意使用的方法实际是什么.$this是web/Application上面是类的继承关系.

1.$id是auditset,load是true.这时var_dump($id)在方法的第一行会出debug说明之前是有这个方法的调用的.
调整一下测试观察的代码

1.加一个debug的标识,我要观察的auditset打断.
2.$this->_modules里面是什么?是配置给application的modules映射列表.

这个setInstance很有意思

其实是维护了一个全局的状态,通过Yii::$app这个类.光看这个调用$module->setInstance($module)是把自己注册到自己身上.有点儿怪怪的.
总之诞生了module对象了.是注册的那个

回到上面,开始创建一个controller,会转回去,解析admin/apply/index,

admin 是找不到module的,那么就是controller的id了.controllerid要么是最后一个字段了没有/
要么是admin/X 和 X+1...到结尾的action,比如 admin/apply/index 就是admin/apply 和index

在寻找controller class的时候class_exists返回的是false,最后对比命名空间发现少写了一个字母,我的类定义里面!
好吧,路由解析就到这儿了.
本文详细记录了一次在yii2.0.1框架中遇到的路由访问问题,从分析源码的角度,逐步揭示了路由解析的流程。作者首先通过文档了解需求,然后定位到Application类的报错方法,分析了route和param的生成,发现报错在于创建action对象时。进一步研究发现,由于模块和控制器映射的问题导致路由解析错误,最终在命名空间中找到了问题的根源——类定义拼写错误。
277

被折叠的 条评论
为什么被折叠?



