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 相关文章推荐
php中使用__autoload()自动加载未定义类的实现代码
Feb 06 PHP
windows的文件系统机制引发的PHP路径爆破问题分析
Jul 28 PHP
php通过Chianz.com获取IP地址与地区的方法
Jan 14 PHP
PHP获取音频文件的相关信息
Jun 22 PHP
PHP给文字内容中的关键字进行套红处理
Apr 12 PHP
PHP设置Cookie的HTTPONLY属性方法
Feb 09 PHP
PHP后端银联支付及退款实例代码
Jun 23 PHP
PHP区块查询实现方法分析
May 12 PHP
php-fpm.conf配置文件中文说明详解及重要参数说明
Oct 10 PHP
PDO::errorCode讲解
Jan 28 PHP
PHP基于openssl实现非对称加密代码实例
Jun 19 PHP
PHP xpath提取网页数据内容代码解析
Jul 16 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数组函数序列之asort() - 对数组的元素值进行升序排序,保持索引关系
2011/11/02 PHP
PHP json格式和js json格式 js跨域调用实现代码
2012/09/08 PHP
php操作xml并将其插入数据库的实现方法
2016/09/08 PHP
php curl 模拟登录并获取数据实例详解
2016/12/22 PHP
PHP在同一域名下两个不同的项目做独立登录机制详解
2017/09/22 PHP
php下的原生ajax请求用法实例分析
2020/02/28 PHP
一端时间轮换的广告
2006/06/26 Javascript
JavaScript DOM 学习第九章 选取范围的介绍
2010/02/19 Javascript
Jquery异步请求数据实例代码
2011/12/28 Javascript
ASP.NET jQuery 实例13 原创jQuery文本框字符限制插件-TextArea Counter
2012/02/03 Javascript
无闪烁更新网页内容JS实现
2013/12/19 Javascript
jQuery的$.proxy()应用示例介绍
2014/04/03 Javascript
Node.js安装教程和NPM包管理器使用详解
2014/08/16 Javascript
jQuery中prop()方法用法实例
2015/01/05 Javascript
js读取并解析JSON类型数据的方法
2015/11/14 Javascript
基于javascript代码实现通过点击图片显示原图片
2015/11/29 Javascript
jQuery+CSS3+Html5实现弹出层效果实例代码(附源码下载)
2016/05/16 Javascript
基于JS实现textarea中获取动态剩余字数的方法
2016/05/25 Javascript
BootStrap树状图显示功能
2016/11/24 Javascript
详细AngularJs4的图片剪裁组件的实例
2017/07/12 Javascript
JS实现区分中英文并统计字符个数的方法示例
2018/06/09 Javascript
解决Js先触发失去焦点事件再执行点击事件的问题
2018/08/30 Javascript
如何实现iframe父子传参通信
2020/02/05 Javascript
Vue循环遍历选项赋值到对应控件的实现方法
2020/06/22 Javascript
python多线程编程方式分析示例详解
2013/12/06 Python
python 获取sqlite3数据库的表名和表字段名的实例
2019/07/17 Python
Python编写通讯录通过数据库存储实现模糊查询功能
2019/07/18 Python
Python 自动登录淘宝并保存登录信息的方法
2019/09/04 Python
iPython pylab模式启动方式
2020/04/24 Python
手把手教你如何用Pycharm2020.1.1配置远程连接的详细步骤
2020/08/07 Python
某个公司的Java笔面试题
2016/03/11 面试题
四风对照检查剖析材料
2014/10/07 职场文书
2015年毕业生自荐信范文
2015/03/24 职场文书
SpringBoot工程下使用OpenFeign的坑及解决
2021/07/02 Java/Android
服务器SVN搭建图文安装过程
2022/06/21 Servers
GoFrame框架数据校验之校验结果Error接口对象
2022/06/21 Golang