yii2 內部規定了 __construct 函數的構造形式,以鍵值對兒數組做爲參數,進行屬性的初始化,但要注意給屬性賦值的工做是轉交給基類 yii\base\Yii::configure 方法的,故沒法直接訪問本類的私有屬性進行初始化工做 ,但咱們能夠使用屬性的 setter/getter 方法來完成php
yii2 在實例化一個類時能夠將此類的屬性以 key=>value 的數組形式傳參初始化本類的一些屬性數組
全部的組件的構造函數都繼承至 yii\base\Object::__construct()安全
這裏須要注意的是,yii2 以安全爲原則,並無將類的私有屬性開放給初始化的參數數組,緣由是 __construct 中的初始工做是調用的 yii\base\Yii::configure() 方法,上下文切換到本類外部,沒法訪問私有變量(這裏便引出了 php 的私有變量訪問域和 __set/__get魔術方法)yii2
/** * Constructor. * The default implementation does two things: * * - Initializes the object with the given configuration `$config`. * - Call [[init()]]. * * If this method is overridden in a child class, it is recommended that * * - the last parameter of the constructor is a configuration array, like `$config` here. * - call the parent implementation at the end of the constructor. * * @param array $config name-value pairs that will be used to initialize the object properties */ public function __construct($config = []) { if (!empty($config)) { //轉到外部調用,故沒法直接訪問當前須要用來初始的 $this 的私有屬性 Yii::configure($this, $config); } $this->init(); }
私有屬性只能在類內部被直接訪問,同時咱們也能夠經過 php 的 __set/__get 魔術方法對其進行封裝訪問app
yii2 的屬性有一套 setter/getter 方法用來承接外部訪問本類的私有屬性,其是對 php 的 __set/__get 魔術方法的封裝,當咱們訪問類的私有屬性時,會觸發 __set/__get 方法,在 yii\base\Object 中框架
/** * Returns the value of an object property. * * Do not call this method directly as it is a PHP magic method that * will be implicitly called when executing `$value = $object->property;`. * @param string $name the property name * @return mixed the property value * @throws UnknownPropertyException if the property is not defined * @throws InvalidCallException if the property is write-only * @see __set() */ public function __get($name) { $getter = 'get' . $name; if (method_exists($this, $getter)) { return $this->$getter(); } elseif (method_exists($this, 'set' . $name)) { throw new InvalidCallException('Getting write-only property: ' . get_class($this) . '::' . $name); } else { throw new UnknownPropertyException('Getting unknown property: ' . get_class($this) . '::' . $name); } } /** * Sets value of an object property. * * Do not call this method directly as it is a PHP magic method that * will be implicitly called when executing `$object->property = $value;`. * @param string $name the property name or the event name * @param mixed $value the property value * @throws UnknownPropertyException if the property is not defined * @throws InvalidCallException if the property is read-only * @see __get() */ public function __set($name, $value) { $setter = 'set' . $name; if (method_exists($this, $setter)) { $this->$setter($value); } elseif (method_exists($this, 'get' . $name)) { throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name); } else { throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name); } }
可見 yii2 會去檢測是否設定了此類某私有屬性的 setter/getter 方法,若是存在則能夠進行訪問,注意 php 的函數/方法/類名是不區分大小寫的,setName 和 setname 沒什麼區別....注意就好,設定了私有屬性的 setter/getter 接口方法,在實例化時參數數組也能夠包含私有屬性的值了,推薦此類方法,在封裝的同時也沒有破壞yii2框架的統一性yii
public function __construct(array $config, $name) { parent::__construct($config); $this->_name= $name; }
如上所示,咱們在繼承父類的構造方法的同時,本身增長新的構造參數,來傳遞給咱們本類的私有變量,但這樣寫向下兼容性會變得不好,不推薦函數
這裏要單獨說一下 Component 的 setter/getter 方法,Component 對 Object 的 setter/getter 方法進行了重寫,以知足本身除 屬性 Property 外的 Event 和 Behavior 的配置this
yii\base\Objectspa
|--yii\base\Event
|--yii\base\Behavior
|--yii\bae\Component
基礎的 setter/getter 方法定義在 yii\base\Object 並被其下三大基類繼承,但並不能知足組件 Component 的配置,由於 Component 組件還包含了 Event 和 Behavior 等配置項的設定
public function __set($name, $value) { $setter = 'set' . $name; if (method_exists($this, $setter)) { // set property $this->$setter($value); return; } elseif (strncmp($name, 'on ', 3) === 0) { // on event: attach event handler $this->on(trim(substr($name, 3)), $value); return; } elseif (strncmp($name, 'as ', 3) === 0) { // as behavior: attach behavior $name = trim(substr($name, 3)); $this->attachBehavior($name, $value instanceof Behavior ? $value : Yii::createObject($value)); return; } else { // behavior property $this->ensureBehaviors(); foreach ($this->_behaviors as $behavior) { if ($behavior->canSetProperty($name)) { $behavior->$name = $value; return; } } } if (method_exists($this, 'get' . $name)) { throw new InvalidCallException('Setting read-only property: ' . get_class($this) . '::' . $name); } else { throw new UnknownPropertyException('Setting unknown property: ' . get_class($this) . '::' . $name); } }
//建立一個組件的對象,併爲其設定 on 類的事件 和 as 類的行爲 \Yii::createObject([ "class" => "app\utils\MyTool", "param_1" => $value_1, "param_2" => $value_2, "on begin" => ['app\utils\MyTool', 'beginHandler'], "on end" => ['app\utils\MyTool', 'endHandler'], "as doIt" => [ "class" => "app\behaviors\MyBehavior" ] ]);
能夠看到,當組件初始化時,根據配置參數的格式會路由 on / as 類的配置項至 Event / Behavior 的設定,Event 和 Behaviour 都是爲 Component 提供擴展服務的