您的位置:首页 > 编程语言 > PHP开发

yii运行机制

2015-06-25 10:37 633 查看
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(new CEvent($this));

$this->processRequest();

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

$this->onEndRequest(new CEvent($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) as $name=>$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=new ReflectionMethod($controller, $methodName);

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

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

else

return$controller->$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执行开始之后的事情.现在对整体应该有一个了解了.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: