CodeIgniter源码分析之RouterphpWord格式文档下载.docx
- 文档编号:19243873
- 上传时间:2023-01-04
- 格式:DOCX
- 页数:19
- 大小:20.83KB
CodeIgniter源码分析之RouterphpWord格式文档下载.docx
《CodeIgniter源码分析之RouterphpWord格式文档下载.docx》由会员分享,可在线阅读,更多相关《CodeIgniter源码分析之RouterphpWord格式文档下载.docx(19页珍藏版)》请在冰豆网上搜索。
{
$this->
config=&
load_class('
Config'
'
core'
uri=&
URI'
log_message('
debug'
"
RouterClassInitialized"
}
//--------------------------------------------------------------------
*Settheroutemapping
function_set_routing()
//如果项目是允许通过query_strings的形式,并且有通过$_GET的方式请求控制器的话,则以query_string形式,也就是
//?
c=xx的形式确定路由。
$segments=array();
if($this->
config->
item('
enable_query_strings'
)===TRUEANDisset($_GET[$this->
controller_trigger'
)]))
//上面这里为什么还要判断有没有通过get的方式指定控制器?
其实是因为如果允许query_string的形式请求路由,但是却
//没有通过query_string(或者说是get)的形式指定路由的话(其实就说明这个通过query_string方式的uri是无效的),
//此时,我们依然会采用“段”的形式。
//取得目录名,目录名,控制名和方法名传递的变量名都是可以自定义的,在config/config.php里面。
if(isset($_GET[$this->
directory_trigger'
set_directory(trim($this->
uri->
_filter_uri($_GET[$this->
)])));
$segments[]=$this->
fetch_directory();
//取得控制器名
set_class(trim($this->
fetch_class();
//取得方法名
function_trigger'
set_method(trim($this->
fetch_method();
//。
。
位置1
//Loadtheroutes.phpfile.
//引入关于路由方面的配置信息。
配置文件里面是一个名字为$route的数组。
if(defined('
ENVIRONMENT'
)ANDis_file(APPPATH.'
config/'
.ENVIRONMENT.'
/routes.php'
))
include(APPPATH.'
elseif(is_file(APPPATH.'
config/routes.php'
//下面这个莫名出现的$route变量(注意不是$this->
routes哦),就是写在配置文件里面。
把它copy到$this->
routes。
//这个$routes是用来指定默认控制器和默认方法,404(请求路由不存在)后规定的路由以及一些路由重定向(?
这个重写向的
//实现在Router:
:
_parse_routes()中实现)的信息。
routes=(!
isset($route)OR!
is_array($route))?
array():
$route;
unset($route);
//利用完就干掉。
//根据刚才的配置信息,设定默认控制器,没有的话,就为FLASE。
default_controller=(!
isset($this->
routes['
default_controller'
])OR$this->
]=='
)?
FALSE:
strtolower($this->
]);
//这个判断的位置放得有点怪,我觉得可以放到上面“位置1”的地方,下面的代码是判断刚才有没有通过query_string的方式拿到
//路由信息,如果拿到的话,那么就不再尝试“段”的方式确定路由了。
直接确定路由,结束本函数。
if(count($segments)>
0)
//_validate_quest($segments);
的作用就是确定并设置路由。
//这个函数执行完之后,Router:
$class,Router:
$directory(如果有)都会有相应值。
return$this->
_validate_request($segments);
//下面的_fetch_uri_string()详见:
URI.php,在这个位置只需知道它的作用是:
//从uri中检测处理,把我们确定路由需要的信息(例如“index.php/index/welcome/1”后
//面"
index/welcome/1"
这串)放到$this->
uri_string这个东西中。
_fetch_uri_string();
//上面_fetch_uri_string()完了之后,这个uri_string就会有我们要用的信息,如果为空的话,那么就用把路由设置为默认的。
uri_string=='
)
//移步至Router:
_set_default_controller();
//如果$this->
uri_string不为空,那么,会通过下面的方式确定路由
//这里只是简单地把后缀去掉而已,因为CI允许在uri后面加后缀,但它其实对我们寻找路由是多余,而且会造成影响的,所以先去掉。
_remove_url_suffix();
//把最初的uri,变成数组放在segments里面。
_explode_segments();
//开始找路由。
移步至Router:
_parse_routes();
//设置为由1开始。
_reindex_segments();
*Setthedefaultcontroller
function_set_default_controller()
//在Router:
_set_routing()函数里面有一个操作,是从配置文件里面读取默认控制器名,如果没有就有FALSE。
default_controller===FALSE)
//如果没有默认的话,就报错,结束程序。
//实质上,这个_set_default_controller()仅仅是在uri没有指定控制器,要求访问默认控制器的时候才
//被调用,所以如果连默认控制器都没有,那么可以果断报错。
show_error("
Unabletodeterminewhatshouldbedisplayed.Adefaultroutehasnotbeenspecifiedintheroutingfile."
//如果有,下面我们就来把默认的控制器设置为当前要找的路由。
//这里只是分“有指定默认方法”和“没有指定”两种情况而已。
不过要弄点下面那个$this->
_set_request($x);
CI这几个函数
//也许写得很妙,但是让人看得纠结。
if(strpos($this->
default_controller,'
/'
)!
==FALSE)
$x=explode('
$this->
default_controller);
set_class($x[0]);
set_method($x[1]);
_set_request();
else
set_class($this->
set_method('
_set_request(array($this->
));
//re-indextheroutedsegmentsarraysoitstartswith1ratherthan0
NoURIpresent.Defaultcontrollerset."
*SettheRoute
function_set_request($segments=array())
*下面来解剖一下这个让人纠结的函数。
第一次看的时候差点被它们这几个函数搞晕。
*看,这里有调用Router:
_validate_request();
而Router:
_validate_request()的作用是检测寻找出一个
*正确存在的路由,并确定它,确定后的值分别放到Rouer:
$class这些属性里面。
所以使到这个_set_request()也有
*这种确定路由的功能。
*
*注:
*$segments=$this->
等式右边,括号里面的这个$segments,也就是调用
*_set_request()时传入来的这个参数,它有这样的特点:
*1)如果这时_set_request()是在Router:
_set_default_controller()中调用的话,那个这个$segments是永远不会为
*空数组,嗯,绝对不会。
*而左边这个$segments的值,经过下面这行代码后,要么为空数组array(),要么为确定路由后的段数组。
*为空数组的原因是,$this->
里面没有找到当前目录的默认控制器。
此时,右边的
*$segments要么为空,要么只指定了目录但默认控制器不存在。
$segments=$this->
if(count($segments)==0)
//所以如果上面返回了空数组,就会进到这里。
//这里居然又调回了_set_default_controller()!
坑爹吧!
*我曾经想过,下面这里会不会死循环:
*假如,我在配置文件里面的默认控制器设为welcome,然后controllers/下没有welcome.php,但controllers/下有
*welcome/有这个目录(里面没东西),然后通过http:
//localhost/CI/来访问默认控制器,那会怎样呢?
*首先,它会进入_set_routing();
然后发现$this->
uri_string为空,进入_set_default_controller();
*然后发现在_set_default_controller里,发现$this->
default_controller不为FALSE,(@@@@),然后再
*进入这_set_request()里面,再进入_validate_request()里面,会不会_validate_request里返回空数组?
因为
*指定了目录,没有指定控制器,访问默认的,又不存在,然后返回空数组,返回空数组后,最终就会走来你正在看的这个位置,
*然后这个位置再调用_set_default_controller();
然后死循环了。
*答案是不会的。
*原因在于:
*我们回到上面解译那个(@@@@)的地方,在这里,发现$this->
default_controller不为FALSE后,它会进入这个else
*里面
*else
*{
*$this->
..............1
...................2
..........3
*}
*然后第3行,传入_set_request($segments)中的那个$segments其实是
*array('
welcome'
'
),重点在于那个小小的'
!
*这样一来,我们进入_validate_request()的时候,我们实质并没有“指定目录但没有指定控制器,访问默认控制器”,
*而是“指定了一个welcome的目录,和一个叫index的控制器!
!
”,所以才不会死循环。
*如果你试着把第3行那个'
去掉,那么,一定会死循环!
不信试试!
CI太牛逼了,居然这样做。
汗。
*当然,‘index’还有一个作用,就是设置默认方法啦。
set_class($segments[0]);
if(isset($segments[1]))
//Astandardmethodrequest
set_method($segments[1]);
$segments[1]='
//这里要说一下,现在是在ROUTER里面为URI赋值,URI里面的这个URI:
$rsegments是经过处理,并确定路由后,实质调用的路由的段信息。
//而URI:
$segments(前面少了个r),则是原来没处理前的那个,即直接由网址上面得出来的那个。
rsegments=$segments;
*Validatesthesuppliedsegments.Attemptstodeterminethepathto
*thecontroller.
function_validate_request($segments)
return$segments;
if(file_exists(APPPATH.'
controllers/'
.$segments[0].'
.php'
//如果直接在controllers这个目录下找到与第一段相应的控制器名,那就说明找到了控制器,确定路由,返回。
//如果上面没有找到,再看看这个“第一段”是不是一个目录,因为CI是允许控制器放在自定义的目录下的。
if(is_dir(APPPATH.'
.$segments[0]))
//Setthedirectoryandremoveitfromthesegmentarray
//如果的确是目录,那么就可以确定路由的目录部分了。
set_directory($segments[0]);
//去掉目录部分。
进一步进行路由寻找。
$segments=array_slice($segments,1);
//如果uri请求中除了目录还有其它“段”,那说明是有请求某指定控制器的。
//指定请求的控制器找不到的话,那只好报错了。
if(!
file_exists(APPPATH.'
.$this->
fetch_directory().$segments[0].'
//报错也有两方式,一种是默认的,一种是自义定的。
//下面这个404_override就是在config/routes.php定义的一个路由找不到时候的默认处理控制器了,如果有定义
//我们调用它。
empty($this->
404_override'
]))
set_directory('
//把刚才设置好的路由的目录部分去掉,因为现在路由是我们定义的404路由。
//这里可以看出,我们定义的404路由是不允许放在某个目录下的,只能直接放在controllers/下
set_method(isset($x[1])?
$x[1]:
'
//默认是index方法
return$x;
//同样,返回“段”数组
//默认找不到路由的方法。
在core/Common.php中定义的全局函数(实质调用Exception组件进行处理)。
show_404($this->
fetch_directory().$segments[0]);
//来到这里,说明了是uri请求指定了目录,而没有指定控制器的情况下。
那么,我们默认当前路由是在当前目录下请求默认的
//控制器和方法。
//下面这个判断只是判断一下$this->
default_controller有没有指定方法而已。
//没有的话就默认为index方法。
//Doesthedefaultcontrollerexistinthesub-folder?
//如果连默认控制器都不存在的话,就无语了,说明uri打算请求这个目录的默认控制器,结果没有这个默认控制器,那暂时
//返回个空数组。
(但是看清楚,上面已经$this->
set_class()了,说明即使没有,我们也已经把默认控制器的名字算
//是确定下来先)
fetch_directory().$this->
default_controller.'
directory='
returnarray();
//能够有命来到这一步,是说明的确是某个目录下找到了控制器,或者是找到了定义的默认控制器。
//但是注意,这个$segments返回的“段”信息都是不包括目录的。
它是一个数组形式,第一个元素是控制器名。
//例如:
array('
acontroller'
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- CodeIgniter 源码 分析 Routerphp