1、類的屬性
Yii中爲Object基類規定義了屬性:屬性支持get、set特性。
1.1getter特性和setter特性
當繼承yii\base\Object的類有一個public function getXxx()方法時,可以直接通過echo $obj->xxx來輸出getXxx方法的返回值。
總結:關鍵是方法要public,然後是get開頭,get後面的單詞就是訪問的屬性名,方法不能有參數
當你定義了public function setAge($value)的時候,執行$obj->age = 9就會觸發setAge($value)方法,而這個$value就是賦過來的值
總結:方法也要public,命名前綴則是set開頭,接收一個$value參數處理等號賦的值
如果只提供了getter,那麼該屬性爲只讀屬性,只提供了setter,則爲只寫。
1.2Object和Component
yii\base\Component 繼承自 yii\base\Object ,因此,他也具有屬性等基本功能。但是,由於Componet還引入了事件、行爲,
因此,Component類具有三個重要的特性:
- 屬性(property)
- 事件(event)
- 行爲(behavior)
1.3、Yii中就是統一使用數組的方式對對象進行配置
Application對象的配置就是這種配置方式的體現:
$config = yii\helpers\ArrayHelper::merge(
require(__DIR__ . '/../../common/config/main.php'),
require(__DIR__ . '/../../common/config/main-local.php'),
require(__DIR__ . '/../config/main.php'),
require(__DIR__ . '/../config/main-local.php')
);
$application = new yii\web\Application($config);
那是因爲yii\base\Object 定義的構造函數中:
public function __construct($config = [])
{
if (!empty($config)) {
Yii::configure($this, $config);
}
$this->init();
}
- 構建函數以 $config 數組爲參數被自動調用。
- 構建函數調用 Yii::configure() 對對象進行配置。
- 在最後,構造函數調用對象的 init() 方法進行初始化。
Yii::configure
可以將一個與類的屬性名對應的數組值注入到類的屬性中。原因在於:
public static function configure($object, $properties)
{
foreach ($properties as $name => $value) {
$object->$name = $value;
}
return $object;
}
1.4、可以在new的時候進行屬性注入
namespace app;
class Test extends \yii\base\Object{
public $name;
public $age;
}
//然後在控制器裏看看效果
$config = [
'name' => 'Jay',
'age' => 26,
];
$test = new Test($config);
print_r([$test->name, $test->age]);
問題:如果配置數組的某個配置項,也是一個數組, 或者如果一個對象的屬性,是另一個對象,這兩種情況實質是一樣的,嵌套配置數組,在Yii的配置文件中,可以看到一個配置項 components
'components' => [
'request' => [
'cookieValidationKey' => 'v7mBbyetv4ls7t8UIqQ2IBO60jY_wf_U',
],
'user' => [
'identityClass' => 'common\models\User',
'enableAutoLogin' => true,
],
'log' => [
'traceLevel' => YII_DEBUG ? 3 : 0,
'targets' => [
[
'class' => 'yii\log\FileTarget',
'levels' => ['error', 'warning'],
],
],
],
'errorHandler' => [
'errorAction' => 'site/error',
],
],
2、事件
1:事件既是代碼解耦的一種方式,也是設計業務流程的一種模式,使用事件,可以在特定的時點,觸發執行預先設定的一段代碼。
2:Yii 中yii\base\Object 不支持事件。 如果一個類需要觸發事件就應該繼承 yii\base\Component 或其子類。
3:Yii中還有一個與事件緊密相關的 yii\base\Event ,他封裝了與事件相關的有關數據,並提供一些功能函數作爲輔助:
event類代碼如下:
class Event extends Object
{
public $name; // 事件名
public $sender; // 事件發佈者,通常是調用了 trigger() 的對象或類。
public $handled = false; // 是否終止事件的後續處理
public $data; // 事件相關數據
private static $_events = [];
public static function on($class, $name, $handler, $data = null,
$append = true)
{
// ... ...
// 用於綁定事件handler
}
public static function off($class, $name, $handler = null)
{
// ... ...
// 用於取消事件handler綁定
}
public static function hasHandlers($class, $name)
{
// ... ...
// 用於判斷是否有相應的handler與事件對應
}
public static function trigger($class, $name, $event = null)
{
// ... ...
// 用於觸發事件
}
}
2.1、事件handler
handler裏就是寫業務邏輯的地方了,對於一個事件handler,可以是以下的形式提供:
- 一個PHP全局函數的函數名,不帶參數和括號,光禿禿的就一個函數名。如 trim ,注意,不是 trim($str) 也不是 trim() 。
- 一個對象的方法,或一個類的靜態方法。如 $person->sayHello() 可以用爲事件handler,但要改寫成以數組的形式, [$person, 'sayHello'] ,而如果是類的靜態方法,那應該是 ['namespace\to\Person', 'sayHello'] 。
- 匿名函數。如 function ($event) { ... }
但無論是何種方式提供,一個事件handler必須具有以下形式:
function ($event) {
// $event 就是前面提到的 yii\base\Event
}
————此處應該通過一個例子來解決事件的定義,綁定,接觸,觸發,等功能(未完,待續)————
3、行爲(可以動態添加方法屬性
)
1:使用行爲(behavior)可以在不修改現有類的情況下,對類的功能進行擴充。 通過將行爲綁定到一個類,可以使類具有行爲本身所定義的屬性和方法,就好像類本來就有這些屬性和方法一樣。 而且不需要寫一個新的類去繼承或包含現有類。
2:Yii中的行爲,其實是 yii\base\Behavior 類的實例, 只要將一個Behavior實例綁定到任意的 yii\base\Component 實例上, 這個Component就可以擁有該Behavior所定義的屬性和方法了。注意,Behavior只能與Component類綁定,所以,如果你寫了一個類,需要使用到行爲,那麼就果斷地繼承自 yii\base\Component 。
3:這個與 object中數組進行屬性注入是有區別的,區別在於使用行爲時纔會有這個屬性,不使用時沒有,而注入,則永遠有這個屬性。
3.1寫一個行爲代碼:
class Behavior extends Object
{
// 指向行爲本身所綁定的Component對象
public $owner;
// Behavior 基類本身沒用,主要是子類使用,重載這個函數返回一個數組表
// 示行爲所關聯的事件
public function events()
{
return [];
}
// 綁定行爲到 $owner
public function attach($owner)
{
... ...
}
// 解除綁定
public function detach()
{
... ...
}
}
3.2使用行爲
一個綁定了行爲的類,表現起來是這樣的:
// Step 1: 定義一個將綁定行爲的類
class MyClass extends yii\base\Component
{
// 空的
}
// Step 2: 定義一個行爲類,他將綁定到MyClass上
class MyBehavior extends yii\base\Behavior
{
// 行爲的一個屬性
public $property1 = 'This is property in MyBehavior.';
// 行爲的一個方法
public function method1()
{
return 'Method in MyBehavior is called.';
}
}
$myClass = new MyClass();
$myBehavior = new MyBehavior();
// Step 3: 將行爲綁定到類上
$myClass->attachBehavior('myBehavior', $myBehavior);
// Step 4: 訪問行爲中的屬性和方法,就和訪問類自身的屬性和方法一樣
echo $myClass->property1;
echo $myClass->method1();
3.3行爲的綁定
上例中綁定行爲直接調用yii\base\Compoent::attachBehaviors(),這個是動態綁定的方法,還有個靜態綁定方式:
靜態綁定行爲,只需要重載 yii\base\Component::behaviors() 就可以了。 這個方法用於描述類所具有的行爲。如何描述呢? 使用配置來描述,可以是Behavior類名,也可以是Behavior類的配置數組:
————具體操作有待進一步理解——
3.4查看綁定好的行爲
對於命名的行爲,可以調用 yii\base\Component::getBehavior() 來取得這個綁定好的行爲:
$behavior = $Component->getBehavior('myBehavior2');
對於匿名的行爲,則沒有辦法直接引用了。但是,可以獲取所有的綁定好的行爲:
$behaviors = $Component->getBehaviors();
3.5解除行爲
解除行爲只需調用 yii\base\Component::detachBehavior() 就OK了: