YII 的源码分析(三)
前面已经看完了启动一个yii程序所要经过的流程,以及渲染一个页面是怎么完成的。今天要分析的是yii是如何处理用户请求的。也就是控制和动作部分。
还是以helloworld为例演示这一过程。我们在地址栏输入http://localhost/study/yii/demos/helloworld/index.php,页面就显示了hello world.
前面的分析都是用的默认值,但是如果url有参数的时候,yii又是怎么处理的呢?带着这个问题,我们具体来分析一下。
在CWebApplication中有这样一行代码:
$route=$this->getUrlManager()->parseUrl($this->getRequest());
这就是传说中的路由了,是不是有点小鸡冻呢?先看看getUrlManager是个神马。
public function getUrlManager()
{
return $this->getComponent('urlManager');
}
这个又要通过找关系了.
public function getComponent($id,$createIfNull=true)
{
if(isset($this->_components[$id]))
return $this->_components[$id];
elseif(isset($this->_componentConfig[$id]) && $createIfNull)
{
$config=$this->_componentConfig[$id];
if(!isset($config['enabled']) || $config['enabled'])
{
Yii::trace("Loading \"$id\" application component",'system.CModule');
unset($config['enabled']);
$component=Yii::createComponent($config);
$component->init();
return $this->_components[$id]=$component;
}
}
}
执行了return $this->_components[$id]; id就是传进去的urlManager,其实从这里也还看不出什么,直接找到urlManager这个类,看parseUrl:
public function parseUrl($request)
{
if($this->getUrlFormat()===self::PATH_FORMAT)
{
$rawPathInfo=$request->getPathInfo();
$pathInfo=$this->removeUrlSuffix($rawPathInfo,$this->urlSuffix);
foreach($this->_rules as $i=>$rule)
{
if(is_array($rule))
$this->_rules[$i]=$rule=Yii::createComponent($rule);
if(($r=$rule->parseUrl($this,$request,$pathInfo,$rawPathInfo))!==false)
return isset($_GET[$this->routeVar]) ? $_GET[$this->routeVar] : $r;
}
if($this->useStrictParsing)
throw new CHttpException(404,Yii::t('yii','Unable to resolve the request "{route}".',
array('{route}'=>$pathInfo)));
else
return $pathInfo;
}
elseif(isset($_GET[$this->routeVar]))
return $_GET[$this->routeVar];
elseif(isset($_POST[$this->routeVar]))
return $_POST[$this->routeVar];
else
return '';
}
从上面的代码来看,如果我们不在url上传点东西,直接就return ''了。于是问题来了,参数要怎么传呢?
isset($_GET[$this->routeVar])
public $routeVar='r';
于是有办法了,让我们一起来使点坏吧。加上这样的一个参数helloworld/index.php?r=abc
发现报错了。说明abc这个控制器是不存在的,事实上也是不存在的,使点小坏坏而已,正所谓男人不坏,女人不爱。
改成helloworld/index.php?r=site就可以显示hello world了,这是什么鬼原理呢?原因很简单,因为定义了site控制器嘛。
class SiteController extends CController
{
/**
* Index action is the default action in a controller.
*/
public function actionIndex()
{
echo 'Hello World';
}
}
好吧,这个我没有意见,但是actionIndex又是神么鬼?在yii中,这称为动作。它捕获的是控制器后面的参数,如果我们输?r=site/index就是index,动作是用“/"进行分隔的,为了验正一下我说的不是骗女孩子的鬼话,我在site控制器里加一个动作给你看一下:
class SiteController extends CController
{
/**
* Index action is the default action in a controller.
*/
public function actionIndex()
{
echo 'Hello World';
} public function actionView()
{
echo 'Hello View';
} }
访问?r=site/view的时候,是不是看到输出'Hello View'了呢?肯定是的,虽然我读的书少,但是你骗不了我的,有图有真相:
我一点儿也不喜欢用site这个名字,test才是我的最爱,于是我又建了一个test控制器来尝试一下。
眼尖的一定看到怎么写了一个actions,这是什么鬼?我也是刚试了才知道,它其实是另一种表示方式。
我记得在blog那个例子中有用过,用来显示验证码:
/**
* Declares class-based actions.
*/
public function actions()
{
return array(
// captcha action renders the CAPTCHA image displayed on the contact page
'captcha'=>array(
'class'=>'CCaptchaAction',
'backColor'=>0xFFFFFF,
),
// page action renders "static" pages stored under 'protected/views/site/pages'
// They can be accessed via: index.php?r=site/page&view=FileName
'page'=>array(
'class'=>'CViewAction',
),
);
}
我把它理解为集中声明第三方业务的动作集合,因为本控制器内的动作,我觉得还是action+ID 的方式直接。
什么鬼?你说我用的是index.php/site/captcha 而不是index.php?r=site/captcha .这又得从配置文件说起。
'urlManager'=>array(
'urlFormat'=>'path',
'rules'=>array(
'post/<id:\d+>/<title:.*?>'=>'post/view',
'posts/<tag:.*?>'=>'post/index',
'<controller:\w+>/<action:\w+>'=>'<controller>/<action>',
),
),
urlFormat 有path 和 get两种,如果在main.php中没有指定,那么就是get方式,也就是index.php?r=site/captcha这种。如果指定了,即index.php/site/captcha这种
从字面上也很好理解,path就是像路径的格式,get就是?这种形式。
关于路由和控制器部分的内容还有很多,但是本节就到这里了。
YII 的源码分析(三)的更多相关文章
- YII框架源码分析(百度PHP大牛创作-原版-无广告无水印)
YII 框架源码分析 百度联盟事业部——黄银锋 目 录 1. 引言 3 1.1.Yii 简介 3 1.2.本文内容与结构 3 2.组件化与模块化 4 2.1.框架加载和运行流程 4 ...
- tomcat源码分析(三)一次http请求的旅行-从Socket说起
p { margin-bottom: 0.25cm; line-height: 120% } tomcat源码分析(三)一次http请求的旅行 在http请求旅行之前,我们先来准备下我们所需要的工具. ...
- 使用react全家桶制作博客后台管理系统 网站PWA升级 移动端常见问题处理 循序渐进学.Net Core Web Api开发系列【4】:前端访问WebApi [Abp 源码分析]四、模块配置 [Abp 源码分析]三、依赖注入
使用react全家桶制作博客后台管理系统 前面的话 笔者在做一个完整的博客上线项目,包括前台.后台.后端接口和服务器配置.本文将详细介绍使用react全家桶制作的博客后台管理系统 概述 该项目是基 ...
- YII 的源码分析(-)
做为源码分析的首秀,我就挑了yii(读作歪依依而不是歪爱爱):它的赞美之词我就不多说了,直接入正题.先准备材料,建议直从官网下载yii的源码包(1.1.15). 在demos里边有一个最简单的应用—h ...
- ABP源码分析三:ABP Module
Abp是一种基于模块化设计的思想构建的.开发人员可以将自定义的功能以模块(module)的形式集成到ABP中.具体的功能都可以设计成一个单独的Module.Abp底层框架提供便捷的方法集成每个Modu ...
- ABP源码分析三十一:ABP.AutoMapper
这个模块封装了Automapper,使其更易于使用. 下图描述了改模块涉及的所有类之间的关系. AutoMapAttribute,AutoMapFromAttribute和AutoMapToAttri ...
- ABP源码分析三十三:ABP.Web
ABP.Web模块并不复杂,主要完成ABP系统的初始化和一些基础功能的实现. AbpWebApplication : 继承自ASP.Net的HttpApplication类,主要完成下面三件事一,在A ...
- ABP源码分析三十四:ABP.Web.Mvc
ABP.Web.Mvc模块主要完成两个任务: 第一,通过自定义的AbpController抽象基类封装ABP核心模块中的功能,以便利的方式提供给我们创建controller使用. 第二,一些常见的基础 ...
- ABP源码分析三十五:ABP中动态WebAPI原理解析
动态WebAPI应该算是ABP中最Magic的功能之一了吧.开发人员无须定义继承自ApiController的类,只须重用Application Service中的类就可以对外提供WebAPI的功能, ...
随机推荐
- mongo遍历表
$mongo = new MongoClient("mongodb://192.168.8.189:27017"); $collectObj = $mongo->select ...
- Mac OS X 中快速访问系统根目录的四种方法
1.通过终端打开Finder的根目录 open / 2.通过“前往文件夹”快捷键组合 用户只需点击左上角的“前往”菜单,然后选择“前往文件夹...”功能.使用快捷键+Shift+G也 ...
- flex的兼容
父容器的 display 属性: .box{ display: -webkit-box; /* 老版本语法: Safari, iOS, Android browser, older WebKit br ...
- substring()
OPENERURL.substring(OPENERURL.indexOf('/sear'));//从/sear开始截取(包括/sear): OPENERURL.substring(OPENERURL ...
- 安装OS X虚拟机错误vcpu-0:VERIFY vmcore/vmm/main/physMem_monitor.c:1123
新建一个虚拟机, 选择客户机操作系统为Apple MacOS X 10.10, 其余参数可以默认. 注意建好之后不要急着打开客户机, 因为直接打开你会发现新建的客户机将会无法启动. 仔细阅读Mac O ...
- 最短路(代码来源于kuangbin和百度)
最短路 最短路有多种算法,常见的有一下几种:Dijstra.Floyd.Bellman-Ford,其中Dijstra和Bellman-Ford还有优化:Dijstra可以用优先队列(或者堆)优化,Be ...
- mac svn命令使用
对mac不熟悉 ssd硬盘又小 不想装版本管理软件. #创建目录 svn mkdir svn://ip.xxx.xxx.xxx/client/ios/opengl/imageToll -m " ...
- java学习之面向对象(3)
下面来谈谈java编程中的一些语法: 1.什么是对象数组? 对象数组就是数组里的每个元素都是类的对象,赋值时先定义对象,然后将对象直接赋值给数组. 对象数组的声明: 类名[] 对象数组名称 = n ...
- NoSQL初探之人人都爱Redis:(4)Redis主从复制架构初步探索
一.主从复制架构简介 通过前面几篇的介绍中,我们都是在单机上使用Redis进行相关的实践操作,从本篇起,我们将初步探索一下Redis的集群,而集群中最经典的架构便是主从复制架构.那么,我们首先来了解一 ...
- iOS开发系列--C语言之数组和字符串
概览 数组在C语言中有着特殊的地位,它有很多特性,例如它的存储是连续的,数组的名称就是数组的地址等.而在C语言中是没有String类型的,那么如果要表示一个字符串,就必须使用字符数组.今天主要就介绍如 ...