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 相关文章推荐
一个简单的MySQL数据浏览器
Oct 09 PHP
windows下升级PHP到5.3.3的过程及注意事项
Oct 12 PHP
PHP 杂谈《重构-改善既有代码的设计》之四 简化条件表达式
Apr 09 PHP
php cc攻击代码与防范方法
Oct 18 PHP
解析mysql left( right ) join使用on与where筛选的差异
Jun 18 PHP
php实现的zip文件内容比较类
Sep 24 PHP
PHP链接MySQL的常用扩展函数
Oct 23 PHP
php分页原理 分页代码 分页类制作教程
Sep 23 PHP
CodeIgniter开发实现支付宝接口调用的方法示例
Nov 14 PHP
thinkphp分页集成实例
Jul 24 PHP
PHP面向对象之里氏替换原则简单示例
Apr 08 PHP
php使用redis的有序集合zset实现延迟队列应用示例
Feb 20 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 文件状态缓存带来的问题
2008/12/14 PHP
PHP跳转页面的几种实现方法详解
2013/06/08 PHP
php实现模拟post请求用法实例
2015/07/11 PHP
PHP使用redis位图bitMap 实现签到功能
2019/10/08 PHP
jquery 图片轮换效果
2010/07/29 Javascript
jQuery+css+html实现页面遮罩弹出框
2013/03/21 Javascript
javascript函数中参数传递问题示例探讨
2014/07/31 Javascript
利用three.js画一个3D立体的正方体示例代码
2017/11/19 Javascript
微信小程序实现的贪吃蛇游戏【附源码下载】
2018/01/03 Javascript
完美解决axios跨域请求出错的问题
2018/02/05 Javascript
vue 左滑删除功能的示例代码
2019/01/28 Javascript
解决Vue+Electron下Vuex的Dispatch没有效果问题
2019/05/20 Javascript
JS浮点数运算结果不精确的Bug解决
2019/08/01 Javascript
layui自定义验证,用ajax查询后台是否有重复数据,form.verify的例子
2019/09/06 Javascript
webpack优化之代码分割与公共代码提取详解
2019/11/22 Javascript
简单介绍使用Python解析并修改XML文档的方法
2015/10/15 Python
python中快速进行多个字符替换的方法小结
2016/12/15 Python
Django模板变量如何传递给外部js调用的方法小结
2017/07/24 Python
Scrapy-Redis结合POST请求获取数据的方法示例
2019/05/07 Python
Pycharm创建项目时如何自动添加头部信息
2019/11/14 Python
Python 使用type来定义类的实现
2019/11/19 Python
python实现两个一维列表合并成一个二维列表
2019/12/02 Python
利用PyQt5+Matplotlib 绘制静态/动态图的实现代码
2020/07/13 Python
浅析NumPy 切片和索引
2020/09/02 Python
python中实现词云图的示例
2020/12/19 Python
python实现ping命令小程序
2020/12/28 Python
Python环境搭建过程从安装到Hello World
2021/02/05 Python
CSS3绘制超炫的上下起伏波动进度加载动画
2016/04/21 HTML / CSS
光声世纪笔试题目
2012/08/25 面试题
教育课题研究自我鉴定范文
2013/12/28 职场文书
优秀士兵个人事迹材料
2014/01/19 职场文书
教师师德演讲稿
2014/05/06 职场文书
师德师风学习材料
2014/12/19 职场文书
三方协议书
2015/01/27 职场文书
主持人开场白台词
2015/05/29 职场文书
SQL Server中T-SQL标识符介绍与无排序生成序号的方法
2022/05/25 SQL Server