欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

yii框架源码分析之创建controller代码

程序员文章站 2023-02-26 17:06:27
使用yii框架的url路径一般形如hostname/?r=xxxx/xxxx/xxxx&sdfs=dsfdsf 我们可以看到有时会使用protected目录下的contro...
使用yii框架的url路径一般形如hostname/?r=xxxx/xxxx/xxxx&sdfs=dsfdsf

我们可以看到有时会使用protected目录下的controller,有时会使用module中controller,具体是如何处理的呢,请看如下的分析:

以下代码摘自yii框架核心代码%yiiroot%/framework/web/cwebapplication.php
复制代码 代码如下:

=================================================================================================
//1.runcontroller是执行一个controller的方法,$route是$_get['r']
public function runcontroller($route)
{
//在这里调用createcontroller先去创建一个controller实例,由此可见createcontroller是选择controller的关键
if(($ca=$this->createcontroller($route))!==null)
{
list($controller,$actionid)=$ca;
$oldcontroller=$this->_controller;
$this->_controller=$controller;
$controller->init();
$controller->run($actionid);
$this->_controller=$oldcontroller;
}
else
throw new chttpexception(404,yii::t('yii','unable to resolve the request "{route}".',
array('{route}'=>$route===''?$this->defaultcontroller:$route)));
}
==================================================================================================
//2.接下来我们分析createcontroller,假设我们访问的route是site/contact
public function createcontroller($route,$owner=null)
{
//首次进入这个函数,$owner参数为空
if($owner===null)
$owner=$this;
//如果$route参数中不含/,那么使用默认的controller
if(($route=trim($route,'/'))==='')
$route=$owner->defaultcontroller;
$casesensitive=$this->geturlmanager()->casesensitive;
//为了能够完整运行下面的循环,给$route后面加一个/
$route.='/';
//将/的位置保存在$pos中
while(($pos=strpos($route,'/'))!==false)
{
//$id是前半部分,即site
$id=substr($route,0,$pos);
if(!preg_match('/^\w+$/',$id))
return null;
if(!$casesensitive)
$id=strtolower($id);
//$route变成后半部分,即contact
$route=(string)substr($route,$pos+1);
//controller根目录或子目录前缀
if(!isset($basepath)) // first segment
{
//首次进入,$owner为空,没有这个成员变量
//非首次进入或$owner有值,有可能设置了这个成员变量,参见cwebmodule类
if(isset($owner->controllermap[$id]))
{
return array(
yii::createcomponent($owner->controllermap[$id],$id,$owner===$this?null:$owner),
$this->parseactionparams($route),
);
}
//如果能通过getmodule方法获取到一个独立模块,则再次调用createcontroller,适用于site是module名的情况,参考protected/config/main.php配置文件,例如你的controller在%webroot%/protected/module/site/controller/contactcontroller.php
if(($module=$owner->getmodule($id))!==null)
return $this->createcontroller($route,$module);
//controller的目录:
//对于cwebapplication,对应config['basepath'](参见配置文件)./controller/,例如你的controller在%webroot%/protected/controller/sitecontroller.php
//对于cmodule的子类,对应改子类所在文件夹./contoller/,例如你的controller在%webroot%/protected/module/site/controller/contactcontroller.php
$basepath=$owner->getcontrollerpath();
$controllerid='';
}
else
$controllerid.='/';
$classname=ucfirst($id).'controller';
$classfile=$basepath.directory_separator.$classname.'.php';
//如果$classfile存在,根据上面所得到的controller类文件路径,创建类实例
//如果不存在,则是子目录下的controller,继续循环寻找最终的controller,例如你的controller在%webroot%/protected/controller/somedir/sitecontroller
if(is_file($classfile))
{
if(!class_exists($classname,false))
require($classfile);
if(class_exists($classname,false) && is_subclass_of($classname,'ccontroller'))
{
$id[0]=strtolower($id[0]);
return array(
new $classname($controllerid.$id,$owner===$this?null:$owner),
$this->parseactionparams($route),
);
}
return null;
}
$controllerid.=$id;
$basepath.=directory_separator.$id;
}
}