URL路由
路由最大的作用就是美化URL地址
SEO相关
配置
取消对于注释
'urlManager'=>array(
'urlFormat'=>'path',
'rules'=>array(
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
),
),
使用
使用之前:http://localhost/yii/testapp/index.php?r=site
使用之后:http://localhost/yii/testapp/index.php/site
实现原理
入口文件
Yii::createWebApplication($config)->run();
执行了 CWebApplication
类的Run
方法
该方法继承自 CApplication
cApplication类:
public function run()
{
if($this->hasEventHandler('onBeginRequest'))
$this->onBeginRequest(new CEvent($this));
register_shutdown_function(array($this,'end'),0,false);
//CWebApplication重写了此方法
$this->processRequest();
if($this->hasEventHandler('onEndRequest'))
$this->onEndRequest(new CEvent($this));
}
面向对象 继承的原则
调用子类,也就是 CWebApplication类
的 processRequest()
方法
CWebApplication类:
public function processRequest()
{
//配置中设置了 catchAllRequest 方法 则调用对于的控制器
//目前我还不知它的应用场景
if(is_array($this->catchAllRequest) && isset($this->catchAllRequest[0]))
{
$route=$this->catchAllRequest[0];
foreach(array_splice($this->catchAllRequest,1) as $name=>$value)
$_GET[$name]=$value;
}
//一般情况下 是执行下面的语句
else
$route=$this->getUrlManager()->parseUrl($this->getRequest());
$this->runController($route);
}
最重要的一句
$route = $this->getUrlManager()->parseUrl($this>getRequest());
//题外话:
//根据 应用组件的了解 所以写成下面这样也是可以的
$route = $this->urlManager->parseUrl($this->request);
这里调用了 CUrlManager类的 parseUrl方法
public function parseUrl($request)
{
if($this->getUrlFormat()===self::PATH_FORMAT)
{
$rawPathInfo=$request->getPathInfo(); //获得pathInfo
$pathInfo=$this->removeUrlSuffix($rawPathInfo,$this->urlSuffix); //删除伪静态
//遍历 路由 规则
//这里的规则 已经在 init()的时候调用的 processRules 包装成了 CUrlRule 对象
foreach($this->_rules as $i=>$rule)
{
if(is_array($rule))
$this->_rules[$i]=$rule=Yii::createComponent($rule);
//这里调用的是 CUrlRule对象的 parseUrl函数 不是递归
if(($r=$rule->parseUrl($this,$request,$pathInfo,$rawPathInfo))!==false)
return isset($_GET[$this->routeVar]) ? $_GET[$this->routeVar] : $r;
}
if($this->useStrictParsing)
throw new CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".',
array('{route}'=>$pathInfo)));
else
return $pathInfo;
}
elseif(isset($_GET[$this->routeVar]))
return $_GET[$this->routeVar];
elseif(isset($_POST[$this->routeVar]))
return $_POST[$this->routeVar];
else
return '';
}
$route
等于 Controller/action 举例 site/index
得到控制器的方法了之后
$this->runController($route);
之后的代码还是挺多的
具体的功能就是 创建对于控制器 调用 对于方法
其他(伪静态)
配置mian.php
'urlManager'=>array(
'urlFormat'=>'path',
'rules'=>array(
'<controller:\w+>/<id:\d+>'=>'<controller>/view',
'<controller:\w+>/<action:\w+>/<id:\d+>'=>'<controller>/<action>',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
),
//伪静态后缀
'urlSuffix'=>'.html'
),
伪静态前:http://localhost/yii/testapp/index.php/site
伪静态后:http://localhost/yii/testapp/index.php/site.html