Yii框架的路由机制分析和规则控制讲解
在Yii Framework中,route是一个非常重要的步骤。通过route我们可以定制更加个性互的Url。同时很多时候,如果route规则复杂也会容易出问题。所以,研究清楚route的机制是十分重要的。在这里希望你能先参看Yii Framework的process flow分析,首先,让我们先看一段代码,此段代码出现在CWebApplication中。
这里我特地连注释也贴过来了,在整个processRequest函数体中主要做的是根据route规则,找到最基本的(原始的)route。这里有点拗口,其实很简单,比如,我们定义了article/read/1这个是我们设置的route规则,article/read?id=1就是我们的原始route。这里可能会有人说,这个不是原始的。这里我只是想说,这里是一种将yii的controller不懂的规则,转换成了controller能明白的规则。
接下来我们逐段来讲解。首先,先说说catchAllRequest,这个主要是用于维护模式的,你使用一个controller去处理所有的请求。我们看25到30行,也可以看出来,当catchAllRequest设置了的话,直接就route就是catchAllRequest中的route。并且将在catchAllRequest中设置的值,附做了GET参数。
有了上面的分析,我们知道,我们的分析重点是第32行!这行程序有很很好的语义性,我们一看就知道是解析Url的。那么他到底是怎么具体实施的呢?首先让我们进入getUrlManager一探究究。
上述代码出现在CWebApplication的基类CApplication中,我们发现其就是获取UrlManager Component。
所以,整个Route的功能其实是由UrlManager实现的。同时Yii强大的扩展性又允许我们可以自己扩展。所以,好好研究这个UrlManager对我们制作自己的Router非常的重要。接下来我们看看,Yii中默认的UrlManager的代码。CUrlManager.php文件还是蛮长的,这里就不贴整个代码了。我逐快分析的。我们这里贴下,类视图
我们发现CUrlManager是继承自CApplicationComponent的,他最关键的一个特点就是继承CComponent,实现IApplicationComponent。
CComponent的特点和行为,我们在Yii中的核心CComponent类详解中已经详细说明,这里就不多说了。关于IApplicationComponent,也很简单,我们看一下他的代码就知道了。
现在我们明白了他的大致的流程,我们现在要看看他是具体如何实现path类型的route解析的。注意上段代码的第16行,这个parseUrl是CUrlRule中的方法,接下来,让我们看看对应的代码。
第11行表示,如果该CUrlRule自身定义的verb(GET,POST)不为空,并且这个verb又不是request的verb,那么这个时候就返回false。
第14行表示,是否大小写敏感,并给标志位赋值。
第19行表示,去除指定的url后缀。
最关键的是35-56行,这里利用了正则表达式,进行了判断。并且当值缺失的时候,赋予默认值。最终返回了route,第53行。
支持我们分析了CUrlManager,最关键的地方还是在CUrlRule的parseUrl方法,也就上述的35-56行。
因此我们要注意,要改变一个route,主要是两个类一个是CUrlManager,另一个是CUrlRule。前者是大局控制的,主要是控制流程还有例外处理等等的。后者才是真正控制规则解析的。