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 17 PHP
php Http_Template_IT类库进行模板替换
Mar 19 PHP
php获取url字符串截取路径的文件名和扩展名的函数
Jan 22 PHP
php调用MySQL存储过程的方法集合(推荐)
Jul 03 PHP
php json_encode值中大括号与花括号区别
Sep 30 PHP
PHP设计模式之装饰者模式代码实例
May 11 PHP
深入理解PHP变量的值类型和引用类型
Oct 21 PHP
php检查页面是否被百度收录
Oct 28 PHP
PHP接收json 并将接收数据插入数据库的实现代码
Dec 01 PHP
PHP编程入门的基本语法知识点总结
Jan 26 PHP
深入理解PHP之源码目录结构与功能说明
Jun 01 PHP
PHP使用星号隐藏用户名,手机和邮箱的实现方法
Sep 22 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开发框架kohana中处理ajax请求的例子
2014/07/14 PHP
PHP传值到不同页面的三种常见方式及php和html之间传值问题
2015/11/19 PHP
php文件上传原理与实现方法详解
2019/12/20 PHP
新浪微博字数统计 textarea字数统计实现代码
2011/08/28 Javascript
jquery $.ajax相关用法分享
2012/03/16 Javascript
jquery无缝向上滚动实现代码
2013/03/29 Javascript
jQuery写的日历(包括日历的样式及功能)
2013/04/23 Javascript
JQUERY实现左侧TIPS滑进滑出效果示例
2013/06/27 Javascript
js函数返回多个返回值的示例代码
2013/11/05 Javascript
JS将表单导出成EXCEL的实例代码
2013/11/11 Javascript
JavaScript判断变量是否为undefined的两种写法区别
2013/12/04 Javascript
jQuery 文本框得失焦点的简单实例
2014/02/19 Javascript
jquery.form.js异步提交表单详解
2017/04/25 jQuery
Vue实战之vue登录验证的实现代码
2017/10/31 Javascript
easyui下拉框动态级联加载的示例代码
2017/11/29 Javascript
vue配置多页面的实现方法
2018/05/22 Javascript
[02:26]2018DOTA2亚洲邀请赛赛前采访-Newbee篇
2018/04/03 DOTA
对pandas中两种数据类型Series和DataFrame的区别详解
2018/11/12 Python
详解用python自制微信机器人,定时发送天气预报
2019/03/25 Python
Django框架模型简单介绍与使用分析
2019/07/18 Python
详解canvas.toDataURL()报错的解决方案全都在这了
2020/03/31 HTML / CSS
新西兰网上购物,折扣店:BestDeals.co.nz
2019/03/20 全球购物
Looking4Parking美国:全球排名第一的机场停车比较品牌
2019/08/26 全球购物
linux面试题参考答案(8)
2016/04/19 面试题
大学生活动策划方案
2014/02/10 职场文书
工作迟到检讨书
2014/02/21 职场文书
小学学习雷锋活动总结
2014/07/03 职场文书
甘南现象心得体会
2014/09/11 职场文书
第二批党的群众路线教育实践活动个人对照检查材料
2014/09/23 职场文书
工作批评与自我批评范文
2014/10/16 职场文书
幼儿园奖惩制度范本
2015/08/05 职场文书
2016秋季运动会开幕词
2016/03/04 职场文书
CSS3新特性详解(五):多列columns column-count和flex布局
2021/04/30 HTML / CSS
js实现模拟购物商城案例
2021/05/18 Javascript
解决IDEA翻译插件Translation报错更新TTK失败不能使用
2022/04/24 Python
Win11怎么添加用户?Win11添加用户账户的方法
2022/07/15 数码科技