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 相关文章推荐
PHP6 先修班 JSON实例代码
Aug 23 PHP
Wordpress 相册插件 NextGEN-Gallery 添加目录将中文转为拼音的解决办法
Dec 29 PHP
php preg_filter执行一个正则表达式搜索和替换
Feb 27 PHP
PDO版本问题 Invalid parameter number: no parameters were bound
Jan 06 PHP
Yii实现多数据库主从读写分离的方法
Dec 29 PHP
php 利用socket发送HTTP请求(GET,POST)
Aug 24 PHP
php用正则判断是否为数字的方法
Mar 25 PHP
php使用preg_match()函数验证ip地址的方法
Jan 07 PHP
PHP读取Excel类文件
May 15 PHP
thinkPHP框架中执行原生SQL语句的方法
Oct 25 PHP
php使用Swoole实现毫秒级定时任务的方法
Sep 04 PHP
ThinkPHP5.1的权限控制怎么写?分享一个AUTH权限控制
Mar 09 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的5个安全措施小结
2012/07/17 PHP
PHP实现数组递归转义的方法
2014/08/28 PHP
php版微信开发Token验证失败或请求URL超时问题的解决方法
2016/09/23 PHP
微信公众平台开发(五) 天气预报功能开发
2016/12/03 PHP
List all the Databases on a SQL Server
2007/06/21 Javascript
基于jquery的finkyUI插件与Ajax实现页面数据加载功能
2010/12/03 Javascript
jQuery使用addClass()方法给元素添加多个class样式
2015/03/26 Javascript
JavaScript处理解析JSON数据过程详解
2015/09/11 Javascript
JS实现新浪微博效果带遮罩层的弹出框代码
2015/10/12 Javascript
JS使用cookie实现DIV提示框只显示一次的方法
2015/11/05 Javascript
基于jQuery实现动态搜索显示功能
2016/05/05 Javascript
JavaScript中的Reflect对象详解(ES6新特性)
2016/07/22 Javascript
bootstrap datepicker 与bootstrapValidator同时使用时选择日期后无法正常触发校验的解决思路
2016/09/28 Javascript
利用Mongoose让JSON数据直接插入或更新到MongoDB
2017/05/03 Javascript
微信浏览器禁止页面下拉查看网址实例详解
2017/06/28 Javascript
浅谈react-native热更新react-native-pushy集成遇到的问题
2017/09/30 Javascript
JS实现移动端触屏拖拽功能
2018/07/31 Javascript
fastadmin中调用js的方法
2019/05/14 Javascript
vue用ant design中table表格,点击某行时触发的事件操作
2020/10/28 Javascript
[38:41]2014 DOTA2国际邀请赛中国区预选赛 LGD VS CNB
2014/05/22 DOTA
Python聊天室实例程序分享
2016/01/05 Python
python 出现SyntaxError: non-keyword arg after keyword arg错误解决办法
2017/02/14 Python
python实现windows壁纸定期更换功能
2019/01/21 Python
Python3模拟curl发送post请求操作示例
2019/05/03 Python
Python上下文管理器用法及实例解析
2019/11/11 Python
Python实现UDP程序通信过程图解
2020/05/15 Python
python正则表达式的懒惰匹配和贪婪匹配说明
2020/07/13 Python
数控加工专业毕业生自荐信
2013/09/27 职场文书
高三自我鉴定范文
2013/10/19 职场文书
项目计划书范文
2014/01/09 职场文书
国际贸易专业个人求职信格式
2014/02/02 职场文书
幼儿园端午节活动方案
2014/08/25 职场文书
房地产销售员岗位职责
2015/04/11 职场文书
银行服务理念口号
2015/12/25 职场文书
浙江省杭州市平均工资标准是多少?
2019/07/09 职场文书
SpringBoot实现异步事件驱动的方法
2021/06/28 Java/Android