Yii 快速学习教程------抽丝剥茧(一) [转]

Yii 快速学习教程------抽丝剥茧(一)  [转]

(2012-05-10 12:46:15)
标签:

杂谈

分类: YII框架详细分析

接触Yii也有一段时间了, 但是仍然对其中的不少东西不甚清楚,于是决定重新开始,并记录下自己的认识和体会. 

抽丝剥茧------了解Yii 在一次请求中完成的具体过程.

1. index.php

Yii::createWebApplication($config)->run();

2. 于是看yii.php 发现Yii 继承自YiiBase,于是可知,其实执行了如下语句:

YiiBase::createWebApplication($config)->run();

3. 进入YiiBase.php

public static function createWebApplication($config=null)

{

return self::createApplication('CWebApplication',$config);

}

4. 于是进入CWebApplication.php, 发现没构造函数且继承自CApplication,再进入CApplication.php

public function __construct($config=null)

{

Yii::setApplication($this);

 

// set basePath at early as possible to avoid trouble

if(is_string($config))

config=require(config);

if(isset($config['basePath']))

{

this>setBasePath(config['basePath']);

unset($config['basePath']);

}

else

$this->setBasePath('protected'); //设置工程基本路径.

Yii::setPathOfAlias('application',$this->getBasePath());//设置应用整个程序的根路径别名.

Yii::setPathOfAlias('webroot',dirname($_SERVER['SCRIPT_FILENAME']));//设置webroot的根路径别名.

Yii::setPathOfAlias('ext',$this->getBasePath().DIRECTORY_SEPARATOR.'extensions');//设置extension的根路径别名.

$this->preinit();

$this->initSystemHandlers(); //初始化异常处理机制

$this->registerCoreComponents();//注册核心组件

//继承关系 CWebApplication -> CApplication -> CModule -> CComponent.

this>configure(config); //CModule中定义, 将config 文件main.php返回的数组,加载为类的自身属性.

this>attachBehaviors(this->behaviors); //在CComponent中定义, 为实例添加行为.

$this->preloadComponents();//加载config文件main.php 中的preload 项

 

$this->init();//加载处理request请求的组件CHttpRequest.于是可触发onBeginRequest 事件.

}

5.一切就绪之后, 运行实际上是CApplication的run函数,处理就此展开了.

public function run()

{

if($this->hasEventHandler('onBeginRequest'))

this>onBeginRequest(newCEvent(this));

$this->processRequest();

if($this->hasEventHandler('onEndRequest'))

this>onEndRequest(newCEvent(this));

}

6.于是查看CWebApplication.php

public function processRequest()

{

if(is_array(this->catchAllRequest) && isset(this->catchAllRequest[0]))

{

route=this->catchAllRequest[0];

foreach(array_splice(this>catchAllRequest,1)asname=>$value)

GET[name]=$value;

}

else

route=this->getUrlManager()->parseUrl($this->getRequest());//解析URL

this>runController(route);//运行Controller

}

 

public function runController($route)

{

if((ca=this->createController($route))!==null) //创建Controller

{

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)));

}

//createController太长因此没有贴出来,功能无非是从$route解析出controller 和action, 查找文件,如果存在, 创建controller实例.

7.因为所有Controller都继承自CCtroller,所以controller>run(actionID)实际上是CController的方法,于是进入CController.php 

public function run($actionID)

{

if((action=this->createAction($actionID))!==null)

{

if((parent=this->getModule())===null)

$parent=Yii::app();

if($parent->beforeControllerAction(this,action))//CWebApplication中定义默认返回为true.即执行前,进行过滤

{

$this->runActionWithFilters(action,this->filters());

$parent->afterControllerAction(this,action);//CWebApplication中定义 用于扩展,默认为空

}

}

else

this>missingAction(actionID);//没有action错误.

}

public function runActionWithFilters(action,filters)

{

if(empty($filters))//是否有过滤条件,没有就直接执行, 有则进行权限过滤

this>runAction(action);

else

{

priorAction=this->_action;

this>action=action;

CFilterChain::create(this,action,$filters)->run();

this>action=priorAction;

}

}

 

public function runAction($action)

{

priorAction=this->_action;

this>action=action;

if(this>beforeAction(action))

{

if(action>runWithParams(this->getActionParams())===false)

this>invalidActionParams(action);

else

this>afterAction(action);

}

this>action=priorAction;

}

8.再一次进入CInlineAction.php 

public function runWithParams($params)

{

methodName=action.this->getId();

controller=this->getController();

method=newReflectionMethod(controller, $methodName);

if($method->getNumberOfParameters()>0)

return this>runWithParamsInternal(controller, method,params);

else

returncontroller>methodName();

}

 

好了,就此打住.来整理一下思绪, 不然脑子真有点乱.

1. 浏览器发送了一个请求, 有代理服务器重定向到index.php, 这里include yii文件和配置文件webroot/config/main.php.并执行.

Yii::createWebApplication($config)->run();

2.由于createWebApplication实际上是Yii继承自父类YiiBase的,所以执行

YiiBase::createWebApplication($config)->run();

3. 创建CWebApplication时, 会先执行其父类CApplication的构造函数, 在构造函数中完成了一下重要的步骤:

  1)初始化系统路径.

  2)初始化路径别名.如 application.component.category = component/category.php

  4). 初始化异常处理

  5)注册核心组件: CHttpSession CAssetManager CWebUser CThemeManager CPhpAuthManager CClientScript CWidgetFactory

  6) 将main.php的配置加载进来, 实例话CHttpRequest

4. 创建对象完成后,再运行run函数,启动处理过程.

    1) 解析URL 分离出controller ID 和actionID

    2) 通过controllerID组织起相应的文件名, 查找相应的类文件,找到则创建类实例,找不到报错结束.

    3) 通过actionID拼接action method, 若没找到,错误结束.若找到执行过滤, 过滤通过后$controller->actionMethod() 返回.

当然这一切还没有提到action执行开始之后的事情.现在对整体应该有一个了解了.
posted @   编程未来  阅读(109)  评论(0编辑  收藏  举报
编辑推荐:
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示