Yii2 例項管理

2021-08-13 22:58:59 字數 3099 閱讀 1515

yii2框架沒有提供類似zendframework3中提供的servicemanager.那麼yii2框架是如何管理物件例項的呢?

長時間使用yii2框架的童鞋一定已經適應了物件中的public變數,以及乙個來自yii\base\component的__set()魔術方法來完成物件構造的過程,但是新鳥如何使用這一切來例項化乙個物件呢?

yii2最擅長的是extends多個物件使他們擁有多個父類的特徵.那麼習慣了zendframework3這種純粹oop的童鞋,有沒有方法既可以盡快適應yii2的簡約,又堅定的不侵犯物件變數的私有性,甚至還能優雅的用注入取代繼承呢?

以下比較物件預設為zendframework3.

在zendframework3中,物件的例項化是我見過相對複雜的.

首先servicemanager會讀取所有已配置模組的module物件(每個模組提供給servicemanager的入口),並根據loadmodules,loadmodule等事件,以特定(可配置的,通過引用不同的內建inte***ce)方式獲取模組配置檔案.

獲得配置檔案時,servicemanager會檢查依賴(如果需要).

一切順利後,servicemanager會依照配置檔案,尋找這個模組或類的工廠.工廠是乙個callable,可以極其複雜,因為每個工廠會接受到整個專案的容器,也就是servicemanager,也可以是簡單的內建,invokefactory.

最終servicemanager會自動的將工廠的產品,也就是這個模組的例項快取到自身的變數中,以便全域性可以訪問.

可見servicemanager是乙個綜合體,用於物件例項的管理,充當全域性容器(裡面甚至包含所有的配置檔案和事件管理模組等所有框架的核心).

你肯定會擔心效能損耗,在小型專案中這種損耗是有的,就像快速排序,面對大宗資料才是它大展身手的時候.也就是說,隨著專案體量的增加,這種損耗的遞增會遠遠低於體量的遞增.

缺點:學習成本很高.

那麼yii2中有這樣的機制嗎?答曰,有.

yii2中居然用乙個近似讓人啼笑皆非的方式解決了這個全域性容器的需求.就是那個**都能看到的靜態呼叫yii.

use yii;

很聰明!但是缺少了保障:

穩定性.這個是我的猜測,將整個框架直接交給乙個yii,真的好嗎?做法等同於將整個框架放入了乙個php陣列,並且這還是個全域性的陣列.

優點:學習成本很低.

yii2在設計上表達了乙個簡單粗暴的觀點,簡單大於一切,甚至效能!

yii2在物件的例項化時居然使用了reflection[淚目.jpg],你沒有看錯,就是那個效能如老狗的反射.為什麼呢?

就為了讓你少些**.

yii::createobject([

'class' => 'foo\bar',

'name' => 'bob'

]);

以上**例項化了乙個foo\bar;物件,並執行了$bar->name = 'bob';,怎麼樣,是不是很簡單?這一切都是reflection的功勞.當然yii::createobject()還有一下用法,更加神奇.

//in foo/bar.php

class

bar}

//in some place.

yii::createobject('foo\bar', [

'param1' => $someclass,//instance from someinte***ce

])

可見.yii::createobject()還可以對你的__construct賦值.不但會檢查引數列表的預設值,物件型別,而且還會為提供可變引數的建構函式檢查php』版本.很貼心有木有?

但是這一切都是reflection提供的.也是在php應用層能解決的唯一途徑.

var_dump(yii::$container->get(test::class) === yii::$container->get(test::class));
上例返回false[懵逼.jpg],怎麼回事,yii2不快取物件嗎?那麼yii2的單例如何實現呢?

原來,yii2中你要想讓自己的物件被快取,只有先yii::$container->set(),再yii::$container->get().setget的引數列表是對稱的.

也就是說,yii2不會自動給你快取物件,實現單例.可能是怕誤導不知道設計模式的初學者,為了對新手友好吧.

setget的具體用法在\yii\di\container的注釋中有非誠詳細的說明.

值得一說的是,作者也意識到頻繁的使用reflection對效能的影響,所以在每次例項化的時候會自動的快取物件的reflection.這點還是非常溫馨的.

yii2中最常見的例項化物件的方法

yii::createobject();
這個東西,這其實只是簡單的對yii\di\containreget()的封裝.

這個方法有兩個引數:

物件設定

這是個陣列,除了'class' => 'someclass'表示這個類的名字外,其他全部代表這個類的屬性.

constructor引數列表

這個沒有什麼好解釋的,就是建構函式的引數列表寫成陣列的形式而已.

其實作文還沒有寫完,我並沒有去yy怎樣去自己實現乙個例項容器模組.因為我想在模組出現在github上的時候,結合readme詳細說明.並在以後的開發中不斷改進.

毫無疑問,yii2是個非常精妙的框架,脾氣也非常清晰,易用大於一切,畢竟用框架開發的專案不會是超大專案.如果追求效能上的極致,可能任何框架都沒法滿足你的要求,甚至是php本身.到那時候的討論可能涉及到更深的層次.就目前而言,就目前的應用層次,看待每乙個框架,你會發現每個作者的思想都有很獨特的地方,可能這個思想本身就已經大於框架本身的意義了,尤其是每個作者展現給我們的,在現實和理想衝突的時候,做出的妥協.

Yii2 選單menu管理

menu表是根據許可權來控制後台選單的顯示和隱藏的。先來看看表結構 table structure for yc menu drop table if exists yc menu create table yc menu id int 11 not null auto increment,name...

yii2框架 yii2自身的自動載入 三

上一節說完了composer的自動載入,下面我們來說一下yii2自身的自動載入。在我們的入口檔案,例如index.php,如下 comment out the following two lines when deployed to production defined yii debug or d...

yii2框架 yii2的asset資源包 十一

link license license use yii web assetbundle author qiang xue since 2.0 定義按需載入css方法,注意載入順序在最後 public static function addcss view,cssfile 將需要載入的檔案已陣列聚合...