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 MYSQL 数据备份类
Jun 19 PHP
腾讯QQ php程序员面试题目整理
Jun 08 PHP
php 截取字符串并以零补齐str_pad() 函数
May 07 PHP
pdo中使用参数化查询sql
Aug 11 PHP
探讨各种PHP字符串函数的总结分析
Jun 05 PHP
PHP引用(&)各种使用方法实例详解
Mar 20 PHP
php查找字符串出现次数的方法
Dec 01 PHP
PHP调用Linux命令权限不足问题解决方法
Feb 07 PHP
php使用APC实现实时上传进度条功能
Oct 26 PHP
thinkPHP简单导入和使用阿里云OSSsdk的方法
Mar 15 PHP
利用PHP_XLSXWriter代替PHPExcel的方法示例
Jul 16 PHP
tp5实现微信小程序多图片上传到服务器功能
Jul 16 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
博士208HAF收音机实习报告
2021/03/02 无线电
php将url地址转化为完整的a标签链接代码(php为url地址添加a标签)
2014/01/17 PHP
浅谈json_encode用法
2015/03/05 PHP
php实现图片上传、剪切功能
2016/05/07 PHP
thinkPHP5框架接口写法简单示例
2019/08/05 PHP
php实现统计IP数及在线人数的示例代码
2020/07/22 PHP
Kibo 用于处理键盘事件的Javascript工具库
2011/10/28 Javascript
js Math 对象的方法
2013/09/01 Javascript
JavaScript实现点击按钮切换网页背景色的方法
2015/10/17 Javascript
jQuery模仿阿里云购买服务器选择购买时间长度的代码
2016/04/29 Javascript
深入浅析JS是按值传递还是按引用传递(推荐)
2016/09/18 Javascript
jQuery图片加载显示loading效果
2016/11/04 Javascript
jQuery获取复选框选中的当前行的某个字段的值
2017/09/15 jQuery
详解从零搭建 vue2 vue-router2 webpack3 工程
2017/11/22 Javascript
JS实现带动画的回到顶部效果
2017/12/28 Javascript
jQuery实现表单动态添加与删除数据操作示例
2018/07/03 jQuery
jQuery实现的别踩白块小游戏完整示例
2019/01/07 jQuery
原生js实现each方法实例代码详解
2019/05/27 Javascript
微信小程序bindtap事件与冒泡阻止详解
2019/08/08 Javascript
微信小程序 拍照或从相册选取图片上传代码实例
2019/08/28 Javascript
5分钟教你用nodeJS手写一个mock数据服务器的方法
2019/09/10 NodeJs
基于Vue.js与WordPress Rest API构建单页应用详解
2019/09/16 Javascript
为什么str(float)在Python 3中比Python 2返回更多的数字
2018/10/16 Python
对Python3 解析html的几种操作方式小结
2019/02/16 Python
Python线上环境使用日志的及配置文件
2019/07/28 Python
使用Python为中秋节绘制一块美味的月饼
2019/09/11 Python
python 消费 kafka 数据教程
2019/12/21 Python
HTML5移动端开发遇见的东西
2019/10/11 HTML / CSS
马德里竞技官方网上商店:Atletico Madrid Shop
2019/03/31 全球购物
公证书样本
2014/04/10 职场文书
党建工作目标管理责任书
2015/01/29 职场文书
校园之声广播稿
2015/08/18 职场文书
子女赡养老人协议书
2016/03/23 职场文书
应用最多的公文《通知》如何写?
2019/04/02 职场文书
据Python爬虫不靠谱预测可知今年双十一销售额将超过6000亿元
2021/11/11 Python
Golang 遍历二叉树
2022/04/19 Golang