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 相关文章推荐
在Windows中安装Apache2和PHP4的权威指南
Oct 09 PHP
PHP4与PHP3中一个不兼容问题的解决方法
Oct 09 PHP
MySQL GBK→UTF-8编码转换
May 24 PHP
PHP下利用header()函数设置浏览器缓存的代码
Sep 01 PHP
深入php-fpm的两种进程管理模式详解
Jun 03 PHP
CI(CodeIgniter)框架介绍
Jun 09 PHP
smarty内置函数config_load用法实例
Jan 22 PHP
PHP中SESSION的注销与清除
Apr 16 PHP
PHP下载远程图片并保存到本地方法总结
Jan 22 PHP
php过滤输入操作之htmlentities与htmlspecialchars用法分析
Feb 17 PHP
laravel5.1框架model类查询的实现方法
Oct 08 PHP
解决laravel中日志权限莫名变成了root的问题
Oct 17 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/10/09 PHP
在CentOS上搭建LAMP+vsftpd环境的简单指南
2015/08/01 PHP
详解PHP对数组的定义以及数组的创建方法
2015/11/27 PHP
php redis setnx分布式锁简单原理解析
2020/10/23 PHP
javascript add event remove event
2008/04/07 Javascript
js操作select控件的几种方法
2010/06/02 Javascript
js判断文本框输入的内容是否为数字
2015/12/23 Javascript
Javascript必知必会(四)js类型转换
2016/06/08 Javascript
jquery中live()方法和bind()方法区别分析
2016/06/23 Javascript
详解Bootstrap的iCheck插件checkbox和radio
2016/08/24 Javascript
基于JS快速实现导航下拉菜单动画效果附源码下载
2016/10/27 Javascript
深入理解选择框脚本[推荐]
2016/12/13 Javascript
WebPack基础知识详解
2017/01/16 Javascript
详解angularjs的数组传参方式的简单实现
2017/07/28 Javascript
vue-content-loader内容加载器的使用方法
2018/08/05 Javascript
vue-router命名视图的使用讲解
2019/01/19 Javascript
[02:08]我的刀塔不可能这么可爱 胡晓桃_1
2014/06/20 DOTA
[56:35]DOTA2上海特级锦标赛主赛事日 - 5 总决赛Liquid VS Secret第一局
2016/03/06 DOTA
[02:01]2018完美盛典-开场舞《双子星》
2018/12/16 DOTA
在Python的Django框架的视图中使用Session的方法
2015/07/23 Python
Python读大数据txt
2016/03/28 Python
pycharm快捷键汇总
2020/02/14 Python
windows10环境下用anaconda和VScode配置的图文教程
2020/03/30 Python
HTML5新增的标签和属性归纳总结
2018/05/02 HTML / CSS
Html5之自定义属性(data-,dataset)
2019/11/19 HTML / CSS
跑鞋、网球鞋、网球拍、服装及装备:Holabird Sports
2016/09/19 全球购物
英国经典球衣网站:Classic Football Shirts
2017/05/20 全球购物
For Art’s Sake官网:手工制作的奢华眼镜
2018/12/15 全球购物
网络、C以及其他硬件方面的面试题
2016/08/23 面试题
解释下列WebService名词:WSDL、SOAP、UDDI
2012/06/22 面试题
毕业生优秀推荐信
2013/11/26 职场文书
打架检讨书100字
2014/01/08 职场文书
单位作风建设自查报告
2014/10/23 职场文书
事业单位聘任报告
2015/03/02 职场文书
银行稽核岗位职责
2015/04/13 职场文书
nginx之内存池的实现
2022/06/28 Servers