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 代码规范小结
Mar 08 PHP
解析php时间戳与日期的转换
Jun 06 PHP
php 删除目录下N分钟前创建的所有文件的实现代码
Aug 10 PHP
php将HTML表格每行每列转为数组实现采集表格数据的方法
Apr 03 PHP
php生成curl命令行的方法
Dec 14 PHP
浅谈PHP的$_SERVER[SERVER_NAME]
Feb 04 PHP
使用PHPMailer发送邮件实例
Feb 15 PHP
PHP实现QQ、微信和支付宝三合一收款码实例代码
Feb 19 PHP
基于php数组中的索引数组和关联数组详解
Mar 12 PHP
yii2 上传图片的示例代码
Nov 02 PHP
PHP设计模式之抽象工厂模式实例分析
Mar 25 PHP
laravel实现于语言包的完美切换方法
Sep 29 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
首页四格,首页五格For6.0(GBK)(UTF-8)[12种组合][9-18][版主安装测试通过]
2007/09/24 PHP
个人写的PHP验证码生成类分享
2014/08/21 PHP
自己写的php中文截取函数mb_strlen和mb_substr
2015/02/09 PHP
php代码架构的八点注意事项
2016/01/25 PHP
Yii中的cookie的发送和读取
2016/07/27 PHP
Jquery Ajax学习实例7 Ajax所有过程事件分析示例
2010/03/23 Javascript
javascript基础第一章 JavaScript与用户端
2010/07/22 Javascript
jQuery.clean使用方法及思路分析
2013/01/07 Javascript
js中array的sort()方法使用介绍
2014/02/20 Javascript
jquery mobile页面跳转后样式丢失js失效的解决方法
2014/09/06 Javascript
ECMAScript 6即将带给我们新的数组操作方法前瞻
2015/01/06 Javascript
Backbone.js中的集合详解
2015/01/14 Javascript
详谈Ajax请求中的async:false/true的作用(ajax 在外部调用问题)
2017/02/10 Javascript
Node.js使用orm2进行update操作时关联字段无法修改的解决方法
2017/06/13 Javascript
vue绑定class与行间样式style详解
2017/08/16 Javascript
Vue导出json数据到Excel电子表格的示例
2017/12/04 Javascript
vue数据传递--我有特殊的实现技巧
2018/03/20 Javascript
浅谈对于“不用setInterval,用setTimeout”的理解
2019/08/28 Javascript
小谈angular ng deploy的实现
2020/04/07 Javascript
[01:07]2015国际邀请赛 中国区预选赛精彩回顾
2015/06/15 DOTA
[01:06]DOTA2亚洲邀请赛专属珍藏-荧煌之礼
2017/03/24 DOTA
详解Python文本操作相关模块
2017/06/22 Python
pandas 获取季度,月度,年度首尾日期的方法
2018/04/11 Python
python实现对输入的密文加密
2019/03/20 Python
python3.6使用tkinter实现弹跳小球游戏
2019/05/09 Python
基于Python的ModbusTCP客户端实现详解
2019/07/13 Python
Django-Model数据库操作(增删改查、连表结构)详解
2019/07/17 Python
python实现加密的方式总结
2020/01/19 Python
详解pandas中iloc, loc和ix的区别和联系
2020/03/09 Python
char型变量中能不能存贮一个中文汉字
2015/07/08 面试题
关于幼儿的自我评价
2013/12/18 职场文书
大学生评语大全
2014/04/18 职场文书
酒店开业庆典策划方案
2014/05/28 职场文书
优秀毕业生自荐信
2014/06/10 职场文书
国家奖学金获奖感言
2014/08/16 职场文书
教你怎么用Python生成九宫格照片
2021/05/20 Python