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 相关文章推荐
Content-type 的说明
Oct 09 PHP
php4的session功能评述(三)
Oct 09 PHP
php a simple smtp class
Nov 26 PHP
Linux下实现PHP多进程的方法分享
Aug 16 PHP
php curl 伪造IP来源的实例代码
Nov 01 PHP
PHP使用Mysqli类库实现完美分页效果的方法
Apr 07 PHP
php并发加锁示例
Oct 17 PHP
php中strlen和mb_strlen用法实例分析
Nov 12 PHP
php微信开发之图片回复功能
Jun 14 PHP
php curl获取https页面内容,不直接输出返回结果的设置方法
Jan 15 PHP
php抽象方法和普通方法的区别点总结
Oct 13 PHP
通过PHP的Wrapper无缝迁移原有项目到新服务的实现方法
Apr 02 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 批量更新网页内容实现代码
2010/01/05 PHP
php url地址栏传中文乱码解决方法集合
2010/06/25 PHP
php 操作调试的方法
2012/07/12 PHP
输入值/表单提交参数过滤有效防止sql注入的方法
2013/12/25 PHP
php使用memcoder将视频转成mp4格式的方法
2015/03/12 PHP
PHP实现163邮箱自动发送邮件
2016/03/29 PHP
PHP实现时间比较和时间差计算的方法示例
2017/07/24 PHP
PHP使用星号替代用户名手机和邮箱的实现代码
2018/02/07 PHP
JavaScript中链式调用之研习
2011/04/07 Javascript
append和appendTo的区别以及appendChild用法
2013/12/24 Javascript
JavaScript实现重置表单(reset)的方法
2015/04/02 Javascript
Javascript实现颜色rgb与16进制转换的方法
2015/04/18 Javascript
jquery简单实现网页层的展开与收缩效果
2015/08/07 Javascript
比较常见的javascript中定义函数的区别
2015/11/09 Javascript
JS验证图片格式和大小并预览的简单实例
2016/10/11 Javascript
关于 jQuery Easyui异步加载tree的问题解析
2016/12/06 Javascript
ES2015 Symbol 一种绝不重复的值
2016/12/25 Javascript
微信小程序实现瀑布流布局与无限加载的方法详解
2017/05/12 Javascript
详解vue嵌套路由-query传递参数
2017/05/23 Javascript
详解JS中的柯里化(currying)
2017/08/17 Javascript
10个最优秀的Node.js MVC框架
2017/08/24 Javascript
vue+element搭建后台小总结 el-dropdown下拉功能
2020/04/10 Javascript
JavaScript事件概念详解(区分静态注册和动态注册)
2021/02/05 Javascript
python文件写入实例分析
2015/04/08 Python
用Pelican搭建一个极简静态博客系统过程解析
2019/08/22 Python
Django app配置多个数据库代码实例
2019/12/17 Python
Python如何实现感知器的逻辑电路
2020/12/25 Python
全球领先的鞋类零售商:The Walking Company
2016/07/21 全球购物
杭州时比特电子有限公司SQL
2013/08/22 面试题
50道外企软件测试面试题
2014/08/18 面试题
Python的两道面试题
2013/06/29 面试题
2014年小学教师工作总结
2014/11/10 职场文书
大足石刻导游词
2015/02/02 职场文书
交通事故被告代理词
2015/05/23 职场文书
考教师资格证不要错过的4个最佳时机
2019/07/17 职场文书
Python中 range | np.arange | np.linspace三者的区别
2022/03/22 Python