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


Posted in PHP onJune 28, 2011

使用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; 
} 
} 
PHP 相关文章推荐
自动跳转中英文页面
Oct 09 PHP
php实现快速排序法函数代码
Aug 27 PHP
解析在PHP中使用mysqli扩展库对mysql的操作
Jul 03 PHP
CodeIgniter实现更改view文件夹路径的方法
Jul 04 PHP
PHP使用CURL_MULTI实现多线程采集的例子
Jul 29 PHP
php中switch与ifelse的效率区别及适用情况分析
Feb 12 PHP
js代码实现微博导航栏
Jul 30 PHP
wampserver改变默认网站目录的办法
Aug 05 PHP
thinkphp实现把数据库中的列的值存到下拉框中的方法
Jan 20 PHP
[原创]php token使用与验证示例【测试可用】
Aug 30 PHP
PHP示例演示发送邮件给某个邮箱
Apr 03 PHP
Yii框架组件的事件机制原理与用法分析
Apr 07 PHP
关于PHP中Object对象的笔记分享
Jun 28 #PHP
php dirname(__FILE__) 获取当前文件的绝对路径
Jun 28 #PHP
php新建文件自动编号的思路与实现
Jun 27 #PHP
调整优化您的LAMP应用程序的5种简单方法
Jun 26 #PHP
php开启安全模式后禁用的函数集合
Jun 26 #PHP
php设计模式 Adapter(适配器模式)
Jun 26 #PHP
php设计模式 Builder(建造者模式)
Jun 26 #PHP
You might like
PHP取余函数介绍MOD(x,y)与x%y
2014/05/15 PHP
CI框架给视图添加动态数据
2014/12/01 PHP
php实现zip文件解压操作
2015/11/03 PHP
php 删除一维数组中某一个值元素的操作方法
2018/02/01 PHP
PHP addAttribute()函数讲解
2019/02/03 PHP
PHP调用QQ互联接口实现QQ登录网站功能示例
2019/10/24 PHP
CLASS_CONFUSION JS混淆 全源码
2007/12/12 Javascript
jQuery 重复加载错误以及修复方法
2014/12/16 Javascript
Nodejs中读取中文文件编码问题、发送邮件和定时任务实例
2015/01/01 NodeJs
jQuery 遍历函数详解
2015/07/05 Javascript
浅析jquery数组删除指定元素的方法:grep()
2016/05/19 Javascript
Backbone中View之间传值的学习心得
2016/08/09 Javascript
浅谈EasyUi ComBotree树修改 父节点选择的问题
2016/11/07 Javascript
微信小程序 解决请求服务器手机预览请求不到数据的方法
2017/01/04 Javascript
巧用weui.topTips验证数据的实例
2017/04/17 Javascript
详解vue-admin和后端(flask)分离结合的例子
2018/02/12 Javascript
解决Webpack 热部署检测不到文件变化的问题
2018/02/22 Javascript
vue组件详解之使用slot分发内容
2018/04/09 Javascript
Node.js应用设置安全的沙箱环境
2018/04/23 Javascript
Vue CL3 配置路径别名详解
2019/05/30 Javascript
vue项目打包为APP,静态资源正常显示,但API请求不到数据的操作
2020/09/12 Javascript
[08:53]DOTA2-DPC中国联赛 正赛 PSG.LGD vs LBZS 选手采访
2021/03/11 DOTA
序列化Python对象的方法
2020/08/01 Python
聊聊python中的循环遍历
2020/09/07 Python
纯HTML5+CSS3制作生日蛋糕代码
2016/11/16 HTML / CSS
HTML5之HTML元素扩展(下)—增强的Form表单元素值得关注
2013/01/31 HTML / CSS
德国专业木制品经销商:Holz-Direkt24
2019/12/26 全球购物
PHP经典面试题
2016/09/03 面试题
描述内存分配方式以及它们的区别
2016/10/15 面试题
计算机应用专业应届毕业生中文求职信范文
2013/11/29 职场文书
研修第一天随笔感言
2014/02/15 职场文书
教师节活动主持词
2014/04/02 职场文书
机关党员公开承诺书
2014/08/30 职场文书
2015大学迎新晚会主持词
2015/07/16 职场文书
《最后一头战象》读后感:动物也有感情
2020/01/02 职场文书
python字典的元素访问实例详解
2021/07/21 Python