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 和 XML: 使用expat函数(一)
Oct 09 PHP
粗略计算在线时间,bug:ip相同
Dec 09 PHP
Zend framework处理一个http请求的流程分析
Feb 08 PHP
php中用数组的方法设置cookies
Apr 21 PHP
php获取mysql数据库中的所有表名的代码
Apr 23 PHP
PHP全概率运算函数(优化版) Webgame开发必备
Jul 04 PHP
PHP使用glob函数遍历目录或文件夹的方法
Dec 16 PHP
PHP处理postfix邮件内容的方法
Jun 16 PHP
php性能分析之php-fpm慢执行日志slow log用法浅析
Oct 17 PHP
PHP实现非阻塞模式的方法分析
Jul 26 PHP
Thinkphp5.0 框架的请求方式与响应方式分析
Oct 14 PHP
一文看懂PHP进程管理器php-fpm
Jun 01 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
一个odbc连mssql分页的类
2006/10/09 PHP
PHP中遍历stdclass object的实现代码
2011/06/09 PHP
用PHP提取中英文词语以及数字的首字母的方法介绍
2013/04/23 PHP
Yii2.0表关联查询实例分析
2016/07/18 PHP
php、mysql查询当天,查询本周,查询本月的数据实例(字段是时间戳)
2017/02/04 PHP
PHP编程文件处理类SplFileObject和SplFileInfo用法实例分析
2017/07/22 PHP
Js基础学习资料
2010/11/23 Javascript
javascript获取select的当前值示例代码(兼容IE/Firefox/Opera/Chrome)
2013/12/17 Javascript
深入讲解AngularJS中的自定义指令的使用
2015/06/18 Javascript
详解JavaScript中双等号引起的隐性类型转换
2016/05/30 Javascript
Three.js学习之Lamber材质和Phong材质
2016/08/04 Javascript
详解nodejs微信公众号开发——5.素材管理接口
2017/04/11 NodeJs
使用vue的v-for生成table并给table加上序号的实例代码
2017/10/27 Javascript
react中使用css的7中方式(最全总结)
2019/02/11 Javascript
VUE单页面切换动画代码(全网最好的切换效果)
2019/10/31 Javascript
Vue.js watch监视属性知识点总结
2019/11/11 Javascript
JS数据类型判断的几种常用方法
2020/07/07 Javascript
python对list中的每个元素进行某种操作的方法
2018/06/29 Python
详解python编译器和解释器的区别
2019/06/24 Python
500行代码使用python写个微信小游戏飞机大战游戏
2019/10/16 Python
python超时重新请求解决方案
2019/10/21 Python
Python闭包与装饰器原理及实例解析
2020/04/30 Python
python如何提升爬虫效率
2020/09/27 Python
Python中openpyxl实现vlookup函数的实例
2020/10/28 Python
一套Delphi的笔试题二
2013/05/11 面试题
岳父生日宴会答谢词
2014/01/13 职场文书
年终晚会活动方案
2014/08/21 职场文书
工作失职检讨书(精华篇)
2014/10/15 职场文书
房屋转让协议书
2014/10/18 职场文书
创先争优承诺书
2015/01/20 职场文书
社区活动总结
2015/02/04 职场文书
关于环保的宣传稿
2015/07/23 职场文书
签证扫盲贴,41个常见签证知识,需要的拿走
2019/08/09 职场文书
劳务派遣管理制度(样本)
2019/08/23 职场文书
Java Socket实现Redis客户端的详细说明
2021/05/26 Redis
OpenCV-Python实现图像平滑处理操作
2021/06/08 Python