久久精品人人爽,华人av在线,亚洲性视频网站,欧美专区一二三

Object和Component的區別是什么

169次閱讀
沒有評論

共計 3893 個字符,預計需要花費 10 分鐘才能閱讀完成。

這篇文章給大家介紹 Object 和 Component 的區別是什么,內容非常詳細,感興趣的小伙伴們可以參考借鑒,希望對大家能有所幫助。

由于 Componet 引入了事件、行為,因此,它并非簡單繼承了 Object 的屬性實現方式,而是基于同樣的機制,重載了 __get() __set() 等函數。但從實現機制上來講,是一樣的。這個不影響理解。

前面說過,官方將 Yii 定位于一個基于組件的框架。可見組件這一概念是 Yii 的基礎。如果你有興趣閱讀 Yii 的源代碼或是 API 文檔,你將會發現,Yii 幾乎所有的核心類都派生于(繼承自) yii\base\Component。

在 Yii1.1 時,就已經有了 component 了,那時是 CComponent。Yii2 將 Yii1.1 中的 CComponent 拆分成兩個類:yii\base\Object 和 yii\base\Component。

其中,Object 比較輕量級些,通過 getter 和 setter 定義了類的屬性 (property)。Component 派生自 Object,并支持事件(event) 和行為(behavior)。因此,Component 類具有三個重要的特性:屬性(property)、事件(event)、行為(behavior)。

相信你或多或少了解過,這三個特性是豐富和拓展類功能、改變類行為的重要切入點。因此,Component 在 Yii 中的地位極高。

在提供更多功能、更多便利的同時,Component 由于增加了 event 和 behavior 這兩個特性,在方便開發的同時,也犧牲了一定的效率。如果開發中不需要使用 event 和 behavior 這兩個特性,比如表示一些數據的類。那么,可以不從 Component 繼承,而從 Object 繼承。典型的應用場景就是如果表示用戶輸入的一組數據,那么,使用 Object。而如果需要對對象的行為和能響應處理的事件進行處理,毫無疑問應當采用 Component。從效率來講,Object 更接近原生的 PHP 類,因此,在可能的情況下,應當優先使用 Object。

Object 的配置方法

Yii 提供了一個統一的配置對象的方式。這一方式貫穿整個 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);

$config 看著復雜,但本質上就是一個各種配置項的數組。Yii 中就是統一使用數組的方式對對象進行配置,而實現這一切的關鍵就在 yii\base\Object 定義的構造函數中:

public function __construct($config = [])

{

if (!empty($config)) {

Yii::configure($this, $config);

}

$this- init();

}

所有 yii\base\Object 的構建流程是:

構建函數以 $config 數組為參數被自動調用。

構建函數調用 Yii::configure() 對對象進行配置。

在最后,構造函數調用對象的 init() 方法進行初始化。

數組配置對象的秘密在 Yii::configure() 中,但說破了其實也沒有什么神奇的:

public static function configure($object, $properties)

{

foreach ($properties as $name = $value) {

$object- $name = $value;

}

return $object;

}

配置的過程就是遍歷 $config 配置數組,將數組的鍵作為屬性名,以對應的數組元素的值對對象的屬性賦值。因此,實現 Yii 這一統一的配置方式的要點有:

繼承自 yii\base\Object。

為對象屬性提供 setter 方法,以正確處理配置過程。

如果需要重載構造函數,請將 $config 作為該構造函數的最后一個參數,并將該參數傳遞給父構造函數。

重載的構造函數的最后,一定記得調用父構造函數。

如果重載了 yii\base\Object::init() 函數,注意一定要在重載函數的開頭調用父類的 init()。

只要實現了以上要點,就可以使得你編寫的類可以按照 Yii 約定俗成的方式進行配置。這在編寫代碼的過程中,帶來許多便利。

像你這么聰明的,肯定會提出來,如果配置數組的某個配置項,也是一個數組,這怎么辦? 如果某個對象的屬性,也是一個對象,而非一個簡單的數值或字符串時,又怎么辦?

這兩個問題,其實是同質的。如果一個對象的屬性,是另一個對象,就像 Application 里會引入諸多的 Component 一樣,這是很常見的。如后面會看到的 $app- request 中的 request 屬性就是一個對象。那么,在配置 $app 時,必然要配置到這個 reqeust 對象。既然 request 也是一個對象,那么他的配置要是按照 Yii 的規矩來,也就是用一個數組來配置它。因此,上面提到的這兩個問題,其實是同質的。

那么,怎么實現呢? 秘密在于 setter 函數。由于 $app 在進行配置時,最終會調用 Yii::configure() 函數。該函數又不區分配置項是簡單的數值還是數組,就直接使用 $object- $name = $value 完成屬性的賦值。那么,對于對象屬性,其配置值 $value 是一個數組,為了使其正確配置。你需要在其 setter 函數上做出正確的處理方式。Yii 應用 yii\web\Application 就是依靠定義專門的 setter 函數,實現自動處理配置項的。比如,我們在 Yii 的配置文件中,可以看到一個配置項 components,一般情況下,他的內容是這樣的:

components = [

request = [

// !!! insert a secret key in the following (if it is empty) –

// this is required by cookie validation

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 ,

],

],

這是一個典型嵌套配置數組。那么 Yii 是如何把他們配置好的呢? 聰明的你肯定想到了,Yii 一定是定義了一個名為 setComponents 的 setter 函數。當然,Yii 并未將該函數放在 yii\web\Application 里,而是放在父類 yii\di\ServiceLocator 里面。至于 ServiceLocator 是何方神圣,在后面 服務定位器(Service Locator) 部分會講到,這里你只需要知道它是 Application 的父類,提供 components 屬性的 setter 方法就可以了:

public function setComponents($components)

{

foreach ($components as $id = $component) {

$this- set($id, $component);

}

}

這里有個成員函數,$this- set(),他是服務定位器用來注冊服務的方法。我們暫時不講這個東西,留待 服務定位器(Service Locator) 部分再講?,F在只要知道這個函數把配置文件中的 components 配置項搞定就可以了。

從 yii\base\Object::__construct() 來看,對于所有 Object,包括 Component 的屬性,都經歷這么 4 個階段:

預初始化階段。這是最開始的階段,就是在構造函數 __construct() 的開頭可以設置 property 的默認值。

對象配置階段。也就是前面提到構造函數調用 Yii::configure($this, $config) 階段。這一階段可以覆蓋前一階段設置的 property 的默認值,并補充沒有默認值的參數,也就是必備參數。$config 通常由外部代碼傳入或者通過配置文件傳入。

后初始化階段。也就是構造函數調用 init() 成員函數。通過在 init() 寫入代碼,可以對配置階段設置的值進行檢查,并規范類的 property。

類方法調用階段。前面三個階段是不可分的,由類的構造函數一口氣調用的。也就是說一個類一但實例化,那么就至少經歷了前三個階段。此時,該對象的狀態是確定且可靠的,不存在不確定的 property。所有的屬性要么是默認值,要么是傳入的配置值,如果傳入的配置有誤或者沖突,那么也經過了檢查和規范。也就是說,你就放心用吧。

關于 Object 和 Component 的區別是什么就分享到這里了,希望以上內容可以對大家有一定的幫助,可以學到更多知識。如果覺得文章不錯,可以把它分享出去讓更多的人看到。

正文完
 
丸趣
版權聲明:本站原創文章,由 丸趣 2023-08-03發表,共計3893字。
轉載說明:除特殊說明外本站除技術相關以外文章皆由網絡搜集發布,轉載請注明出處。
評論(沒有評論)
主站蜘蛛池模板: 拉孜县| 渑池县| 巴林左旗| 衡阳县| 阳西县| 山阳县| 福清市| 长垣县| 吉安市| 栾城县| 孟村| 潞西市| 江西省| 弥渡县| 佛山市| 呼伦贝尔市| 喀喇沁旗| 宁国市| 庐江县| 庆阳市| 南康市| 旬邑县| 福建省| 郴州市| 海兴县| 正阳县| 定襄县| 凤城市| 梁平县| 汾阳市| 宁安市| 凤阳县| 龙口市| 平原县| 桃江县| 曲阜市| 福清市| 托里县| 黄石市| 永川市| 北碚区|