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 相关文章推荐
smarty+adodb+部分自定义类的php开发模式
Dec 31 PHP
让你成为更出色的PHP开发者的10个技巧
Feb 25 PHP
解析php函数method_exists()与is_callable()的区别
Jun 21 PHP
PHP时间格式控制符对照表分享
Jul 23 PHP
php基于curl扩展制作跨平台的restfule 接口
May 11 PHP
四个PHP非常实用的功能
Sep 29 PHP
PHP微信分享开发详解
Jan 14 PHP
PHP基于imagick扩展实现合成图片的两种方法【附imagick扩展下载】
Nov 14 PHP
PHP堆栈调试操作简单示例
Jun 15 PHP
PHP PDOStatement::getColumnMeta讲解
Feb 01 PHP
浅谈PHP中的Trait使用方法
Mar 22 PHP
TP5框架安全机制实例分析
Apr 05 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自动加载的两种实现方法
2010/06/21 PHP
上传文件先创建目录 再上传到目录里面去
2010/12/29 PHP
gd库图片下载类实现下载网页所有图片的php代码
2012/08/20 PHP
php之Memcache学习笔记
2013/06/17 PHP
php中chdir()函数用法实例
2014/11/13 PHP
php调整服务器时间的方法
2015/04/03 PHP
PHP使用file_get_content设置头信息的方法
2016/02/14 PHP
php中使用websocket详解
2016/09/23 PHP
PHP数字前补0的自带函数sprintf 和number_format的用法(详解)
2017/02/06 PHP
Gambit vs ForZe BO3 第一场 2.13
2021/03/10 DOTA
jquery下操作HTML控件的实现代码
2010/01/12 Javascript
JSON 教程 json入门学习笔记
2020/09/22 Javascript
js里的prototype使用示例
2010/11/19 Javascript
JQuery-tableDnD 拖拽的基本使用介绍
2013/07/04 Javascript
禁止拷贝网页内容的js代码
2014/01/22 Javascript
js改变embed标签src值的方法
2015/04/10 Javascript
JavaScript中的Math.sin()方法使用详解
2015/06/15 Javascript
javascript给span标签赋值的方法
2015/11/26 Javascript
关于List.ToArray()方法的效率测试
2016/09/30 Javascript
jQuery插件imgAreaSelect基础讲解
2017/05/26 jQuery
Vue隐藏显示、只读实例代码
2018/07/18 Javascript
NodeJs入门教程之定时器和队列
2019/03/08 NodeJs
在漏洞利用Python代码真的很爽
2007/08/26 Python
Python基于OpenCV实现人脸检测并保存
2019/07/23 Python
Python greenlet和gevent使用代码示例解析
2020/04/01 Python
基于pytorch中的Sequential用法说明
2020/06/24 Python
如何在python中判断变量的类型
2020/07/29 Python
Raffaello Network德国:意大利拉斐尔时尚购物网
2019/05/01 全球购物
自考生自我评价分享
2014/01/18 职场文书
电工工作职责范本
2014/02/22 职场文书
不同意离婚答辩状
2015/05/22 职场文书
大学生学习十八届五中全会精神心得体会
2016/01/05 职场文书
教学反思怎么写
2016/02/24 职场文书
一篇文章带你深入了解Mysql触发器
2021/08/02 MySQL
mysql创建存储过程及函数详解
2021/12/04 MySQL
Win10加载疑难解答时出错发生意外错误的解决方法
2022/07/07 数码科技