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 相关文章推荐
用Socket发送电子邮件(利用需要验证的SMTP服务器)
Oct 09 PHP
PHP 高手之路(二)
Oct 09 PHP
用sql命令修改数据表中的一个字段为非空(not null)的语句
Jun 04 PHP
匹配csdn用户数据库与官方用户的重合度并将重叠部分的用户筛选出来
Dec 25 PHP
php去掉文件前几行的方法
Jul 29 PHP
PHP Mysqli 常用代码集合
Nov 12 PHP
PHP foreach遍历多维数组实现方式
Nov 16 PHP
php下载远程大文件(获取远程文件大小)的实例
Jun 17 PHP
phpStudy配置多站点多域名和多端口的方法
Sep 01 PHP
PHP命令Command模式用法实例分析
Aug 08 PHP
laravel框架如何设置公共头和公共尾
Oct 22 PHP
PHP加MySQL消息队列深入理解
Feb 27 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中的串行化变量和序列化对象
2006/09/05 PHP
使用PHP获取当前url路径的函数以及服务器变量
2013/06/29 PHP
PHP文件上传问题汇总(文件大小检测、大文件上传处理)
2015/12/24 PHP
smarty模板数学运算示例
2016/12/11 PHP
用PHP的socket实现客户端到服务端的通信实例详解
2017/02/04 PHP
php加密之discuz内容经典加密方式实例详解
2017/02/04 PHP
零基础php编程好学吗
2019/10/11 PHP
Z-Blog中用到的js代码
2007/03/15 Javascript
Javascript基础 函数“重载” 详细介绍
2013/10/25 Javascript
js简单的弹出框有关闭按钮
2014/05/05 Javascript
JS实现让网页背景图片斜向移动的方法
2015/02/25 Javascript
Juery解决tablesorter中文排序和字符范围的方法
2015/05/06 Javascript
FullCalendar日历插件应用之数据展现(一)
2015/12/23 Javascript
一览画面点击复选框后获取多个id值的方法
2016/05/30 Javascript
js微信支付实现代码
2016/12/22 Javascript
在vue中使用css modules替代scroped的方法
2018/03/10 Javascript
解决vue 界面在苹果手机上滑动点击事件等卡顿问题
2018/11/27 Javascript
一篇文章,教你学会Vue CLI 插件开发
2019/04/17 Javascript
vuex存储复杂参数(如对象数组等)刷新数据丢失的解决方法
2019/11/05 Javascript
vue-dplayer 视频播放器实例代码
2019/11/08 Javascript
利用js canvas实现五子棋游戏
2020/10/11 Javascript
[11:57]《一刀刀一天》第十七期:TI中国军团加油!
2014/05/26 DOTA
[05:59]2018DOTA2国际邀请赛寻真——只为胜利的Secret
2018/08/13 DOTA
Pyramid将models.py文件的内容分布到多个文件的方法
2013/11/27 Python
Python __setattr__、 __getattr__、 __delattr__、__call__用法示例
2015/03/06 Python
十个Python程序员易犯的错误
2015/12/15 Python
python 爬虫 批量获取代理ip的实例代码
2018/05/22 Python
Python爬取成语接龙类网站
2018/10/19 Python
简单了解Django ORM常用字段类型及参数配置
2020/01/07 Python
Python paramiko使用方法代码汇总
2020/11/20 Python
HTML5自定义视频播放器源码
2020/01/06 HTML / CSS
老海军美国官网:Old Navy
2016/09/05 全球购物
我的大学四年规划书范文2014
2014/09/26 职场文书
爱晚亭导游词
2015/02/09 职场文书
庆祝教师节主题班会
2015/08/17 职场文书
毕业生自荐求职信书写的技巧
2019/08/26 职场文书