Yii: 组件加载逻辑及自定义组件覆盖

72 篇文章 0 订阅
43 篇文章 0 订阅

有时候会遇到自己定义的组件没有被成功加载或者被覆盖的情况,那么就需要搞清楚组件加载的逻辑,以及可能被覆盖的情况。

Yii中组件components的加载是在CApplication被实例化的时候执行的,如下:

	public function __construct($config=null)
	{
		......

		$this->preinit();

		$this->initSystemHandlers();
		$this->registerCoreComponents();
		$this->configure($config);   
		$this->attachBehaviors($this->behaviors);             
		$this->preloadComponents();

		$this->init();
	}
Yii首先调用$this->registerCoreComponents()方法来注册核心组件如错误处理、URL管理、请求、安全管理、日志等,

然后调用$this->configure($config)来加载配置,

接着调用$this->preloadComponents来预先创建在配置文件中列入'preload'配置项的那些组件实例,

最后调用$this->init()进行初始化操作。


那么在配置文件中设置的'components'配置项究竟什么时候生效的呢? 

也就是说如果你定义了自己的urlManager,你的urlManager究竟是什么时候覆盖掉原先已经注册的缺省核心组件的呢?

看起来应该是configure这一步,我们看一下该函数:

	public function configure($config)
	{
		if(is_array($config))
		{
			foreach($config as $key=>$value)
				$this->$key=$value;
		}
	}

很简单的实现,就是把config文件中的各个配置项设置为CApplication的属性键值对,看起来没做任何和组件注册/加载相关的事情。

实际上这里是通过魔法函数来实现自定义组件的注册的,CApplication的基类是CModule,而CModule的基类是CComponent,在调用

$this->components='....'的时候,实际上PHP自动触发了CComponent的__set方法,该方法被Yii重载,

调用了setter方法(set+$name)即setcomponents(注意:PHP函数大小写不敏感,所以实际调用的是CModule类的setComponents方法)来注册了应用自定义的组件。


需要说明的是Yii使用的是延迟加载策略,也就是只有当某个组件实际被使用时,才会被加载,registerCoreComponents和configure方法只是实现了核心组件以及自定义组件的注册(类信息及一些控制参数注册到应用程序属性中),并没有真正创建实例,只有preloadComponents才真正加载了部分类库文件并创建了类实例(createComponent),所以考虑到性能,应该注意尽量减少预加载组件。

现在搞清楚了组件是如何注册和预先加载的,那究竟什么时候自定义组件会失效呢? 

显式的调用setComponents和setComponent当然可以,但有些函数不那么明显,会隐式的覆盖掉已加载的组件,这样更麻烦,

比如CModule::getModule函数,该函数会重新调用模块的初始化函数init(),在初始化的时候,如果该模块设置了自己的components,那么已注册或加载的组件就会被重新覆盖(比如Gii模块)。类似的情况在进行模块和组件依赖关系设计的时候需要注意。


by iefreer, Founder of Techbrood Co.

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值