Yii生命周期

32 篇文章 0 订阅

每一次 Yii 应用开始处理 HTTP 请求时,它都会进行一个近似的流程。

1、用户提交指向 入口脚本 web/index.php 的请求。
2、入口脚本会加载 配置数组 并创建一个 应用 实例用于处理该请求。
3、应用会通过 request(请求) 应用组件 解析被请求的 路由。
4、应用创建一个 controller(控制器) 实例具体处理请求。
5、控制器会创建一个 action(动作) 实例并为该动作执行相关的 Filters(访问过滤器)。
6、如果任何一个过滤器验证失败,该动作会被取消。
7、如果全部的过滤器都通过,该动作就会被执行。
8、动作会加载一个数据模型,一般是从数据库中加载。
9、动作会渲染一个 View(视图),并为其提供所需的数据模型。
10、渲染得到的结果会返回给 response(响应) 应用组件。
11、响应组件会把渲染结果发回给用户的浏览器。

在这里插入图片描述

2、入口脚本会加载 配置数组 并创建一个 应用 实例用于处理该请求。
在这里插入图片描述
生成应用的实例为:CWebApplication

public static function createWebApplication($config=null)
{
	return self::createApplication('CWebApplication',$config);
}

实例化app对象为:framework/base/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']));
	Yii::setPathOfAlias('ext',$this->getBasePath().DIRECTORY_SEPARATOR.'extensions');

	$this->preinit();

	 设置异常处理函数
    // set_exception_handler — 设置用户自定义的异常处理函数
    // set_error_handler — 设置用户自定义的错误处理函数
	$this->initSystemHandlers();
	
	//注册核心组件:CPhpMessageSource、CDbConnection、CPhpMessageSource
    // CErrorHandler、CSecurityManager、CStatePersister、CUrlManager、CHttpRequest、CFormatter
	$this->registerCoreComponents();

	//注册配置数据
	$this->configure($config);
	
	//注册行为
	$this->attachBehaviors($this->behaviors);
	
	//加载配置数组中预定义的组件
	$this->preloadComponents();
	
	//运行加载生产并返回request组件
	$this->init();
}

3、应用会通过 request(请求) 应用组件 解析被请求的 路由。
4、应用创建一个 controller(控制器) 实例具体处理请求。

public function run()
{
	if($this->hasEventHandler('onBeginRequest'))
		$this->onBeginRequest(new CEvent($this));
	//	注册一个 callback ,它会在脚本执行完成或者 exit() 后被调用。
	register_shutdown_function(array($this,'end'),0,false);
	//处理请求:解析路由-》创建controller实例具体请求
	$this->processRequest();
	if($this->hasEventHandler('onEndRequest'))
		$this->onEndRequest(new CEvent($this));
}

public function createController(route,$owner=null){
	//解析路由

	//加载请求controller.php文件

	//创建控制器实例对象,以及action方法名称
	return array(
		new $className($controllerID.$id,$owner===$this?null:$owner),
		$this->parseActionParams($route),
	);
}

5、控制器会创建一个 action(动作) 实例并为该动作执行相关的 Filters(访问过滤器)。
6、如果任何一个过滤器验证失败,该动作会被取消。
执行init()和run()函数

public function runController($route)
{
	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)));
}

//CController的run方法 :加载模块init引入的文件
public function run($actionID)
{
	//实例对象CInlineAction
	if(($action=$this->createAction($actionID))!==null)
	{
		if(($parent=$this->getModule())===null)
			$parent=Yii::app();
		//调用对应模块对象的方法 CWebModule -》CModule-》CComponent -》递归初始化模块	
		if($parent->beforeControllerAction($this,$action))
		{
			$this->runActionWithFilters($action,$this->filters());
			$parent->afterControllerAction($this,$action);
		}
	}
	else
		$this->missingAction($actionID);
}

7、如果全部的过滤器都通过,该动作就会被执行。

//执行action方法
public function runAction($action)
{
	$priorAction=$this->_action;
	$this->_action=$action;
	//先执行beforeAction
	if($this->beforeAction($action))
	{
		if($action->runWithParams($this->getActionParams())===false)
			$this->invalidActionParams($action);
		else
			$this->afterAction($action);
	}
	$this->_action=$priorAction;
}

最终执行 CInlineAction的此方法
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
		//执行路由控制器对应的action方法
		return $controller->$methodName();
}
  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值