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写的小东西
Dec 06 PHP
php xfocus防注入资料
Apr 27 PHP
php htmlspecialchars加强版
Feb 16 PHP
详解php的魔术方法__get()和__set()使用介绍
Sep 19 PHP
定义php常量的详解
Jun 09 PHP
浅谈PHP解析URL函数parse_url和parse_str
Nov 11 PHP
php实现的树形结构数据存取类实例
Nov 29 PHP
PHP生成条形图的方法
Dec 10 PHP
php防止用户重复提交表单
Nov 02 PHP
PHP实现删除多重数组对象属性并重新赋值的方法
Jun 07 PHP
PHP学习笔记之session
May 06 PHP
PHP Pipeline 实现中间件的示例代码
Apr 26 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
探讨如何在php168_cms中提取验证码
2013/06/08 PHP
PHP中的traits实现代码复用使用实例
2015/05/13 PHP
PHP中如何判断exec函数执行成功?
2016/08/04 PHP
tp框架(thinkPHP)实现三次登陆密码错误之后锁定账号功能示例
2018/05/24 PHP
Javascript 布尔型分析
2008/12/22 Javascript
深入理解JavaScript系列(3) 全面解析Module模式
2012/01/15 Javascript
Js参数值中含有单引号或双引号问题的解决方法
2013/11/06 Javascript
JavaScript代码编写中各种各样的坑和填坑方法
2014/06/06 Javascript
JS数组的遍历方式for循环与for...in
2014/07/31 Javascript
使用JavaScript 编写简单计算器
2014/11/24 Javascript
JavaScript中操作Mysql数据库实例
2015/04/02 Javascript
JS闭包、作用域链、垃圾回收、内存泄露相关知识小结
2016/05/16 Javascript
Jquery调用iframe父页面中的元素及方法
2016/08/23 Javascript
ajax分页效果(bootstrap模态框)
2017/01/23 Javascript
微信小程序上滑加载下拉刷新(onscrollLower)分批加载数据(一)
2017/05/11 Javascript
利用Vue实现移动端图片轮播组件的方法实例
2017/08/23 Javascript
vue路由拦截及页面跳转的设置方法
2018/05/24 Javascript
傻瓜式解读koa中间件处理模块koa-compose的使用
2018/10/30 Javascript
python发送邮件脚本
2018/05/22 Python
Python中实现单例模式的n种方式和原理
2018/11/14 Python
python 限制函数执行时间,自己实现timeout的实例
2019/01/12 Python
python ipset管理 增删白名单的方法
2019/01/14 Python
python中append实例用法总结
2019/07/30 Python
tensorflow如何批量读取图片
2019/08/29 Python
详解纯CSS3制作的20种loading动效
2017/07/05 HTML / CSS
CSS3——齿轮转动关键代码
2013/05/02 HTML / CSS
网页中的电话号码如何实现一键直呼效果_附示例
2016/03/15 HTML / CSS
Java基础知识面试题
2014/03/25 面试题
2014年学习全国道德模范事迹思想汇报
2014/09/15 职场文书
2014年维修工作总结
2014/11/22 职场文书
个人委托书范文
2015/01/28 职场文书
民主评议教师党员自我评价
2015/03/04 职场文书
开业庆典致辞
2015/08/01 职场文书
全民创业工作总结
2015/08/13 职场文书
JavaScript实现简单计时器
2021/06/22 Javascript
MyBatis 动态SQL全面详解
2021/10/05 MySQL