菜鸟常忽略的基础 - init方法 ¶
作者:KK
发表日期:2016.9.8
要点速读 ¶
不要随便重写
__construct
方法如果你写了一个类继承了Yii自带的类,那当你要重写构造方法时,请不要重写
__construct
,不然的话经常会出问题的要做初始化工作就重写
init
方法,前提是这个类的父类中有yii\base\Component
或yii\base\Object
(放心大部分都有)官方都说过,所有继承那2个类的子类都有init方法,建议重写这个方法来初始化
为毛要用init? ¶
因为Yii之所以能实现定义这样的功能:
Yii::createObject('A', [
'a' => 1,
'b' => 2,
]);
是因为它的construct大概做了这样的事情:
class Component{
public function __construct($attributes){
foreach($attributes as $name => $attribute){
$this->{$name} = $attribute;
}
$this->init();
}
public function init(){}
}
你重写了__construct的话,这些属性注入就实现不了啦
另外,重写Controller的__construct时会踩到个深坑 ¶
一般其实你重写了__construct
不一定会马上发现问题,因为不一定刚好有底层或者你的代码调用了属性注入的代码嘛(除非是用在组件上)
但是如果你继承了yii\web\Controller
或其他Controller后重写__construct,那保准你跑不起来
因为Yii对Controller的构建方法是另外定制了,属性注入要特殊处理的
且看yii\base\Controller::__construct方法,参数表是这样的:__construct($id, $module, $config = [])
(相关底层处理代码参考:yii\base\Module::createController的Yii::createObject($this->controllerMap[$id], [$id, $this])
这个代码位置)
前面两个参数是底层创建控制器所必须的,如果你重写了__construct又不做好父类的处理,又不同步参数表,那肯定要吃Yii一棒了