Yii PHP 框架分析(三)

2021-06-21 21:08:53 字數 3572 閱讀 6956

yii應用的入口指令碼引用出了yii類,yii類的定義:

class yii extends yiibase

由yiic建立的應用裡yii類只是yiibase類的「馬甲」,我們也可以根據需求定製自己的yii類。

yii(即yiibase)是乙個「helper class」,為整個應用提供靜態和全域性訪問入口。

類自動載入

yii基於php5的autoload機制來提供類的自動載入功能,自動載入器為yiibase類的靜態方法autoload()。

當程式中用new建立物件或訪問到類的靜態成員,php將類名傳遞給類載入器,由類載入器完成類檔案的include。

autoload機制實現了類的「按需匯入」,就是系統訪問到類時才include類的檔案。

yiibase類的靜態成員$_coreclasses 裡預先存放了yii自身的核心類名於對應的類檔案路徑。其他的yii應用中用到的類可以用yii::import() 匯入,yii::import()將單類的與對應類檔案存放於$_classes中,以*萬用字元表示的路徑加入到php include_path中。被yii::import()匯入的類檔案或目錄都記入$_imports中,避免多次匯入。

/* yii::import()

* $alias: 要匯入的類名或路徑

* $forceinclude false:只匯入不include類檔案,true則匯入並include類檔案

*/public static function import($alias,$forceinclude=false)

return $alias;

}// 產生乙個變數 $classname,為$alias最後乙個.後面的部分

// 這樣的:'x.y.classnamer'

// $classname不等於 '*', 並且classnamer類已定義的,      classnamer' 記入 $_imports,直接返回

if(($classname=(string)substr($alias,$pos+1))!=='*' && (class_exists($classname,false) || inte***ce_exists($classname,false)))

return self::$_imports[$alias]=$classname;

// $alias裡含有別名,並轉換真實路徑成功

if(($path=self::getpathofalias($alias))!==false)

// $alias是'system.web.*'這樣的已*結尾的路徑,將路徑加到include_path中

else // a directory

array_unshift(self::$_includepaths,$path);

set_include_path('.'.path_separator.implode(path_separator,self::$_includepaths));

return self::$_imports[$alias]=$path;}}

else

throw new cexception(yii::t('yii','alias "" is invalid. make sure it points to an existing directory or file.',

array(''=>$alias)));

}然後看看 yiibase::autoload() 函式的處理:

public static function autoload($classname)

return true;

}系統配置檔案裡的 import 項裡的類或路徑在指令碼啟動中會被自動匯入。使用者應用裡個別類需要引入的類可以在類定義前加入 yii::import() 語句。

應用元件管理

每個應用元件用乙個字串名字來標識,通過cmodule類的__get() 方法來訪問。

cmodule類的$_components 成員存放應用元件的物件例項($name => $object),$_componentconfig 裡存放應用元件的類名和初始化引數。

使用應用元件的時候,先在$_componentconfig裡設定好元件的類名和初始化引數,在第一次訪問元件的時候,cmodule會自動建立應用元件物件例項並初始化給定的引數,然後會呼叫應用元件的init()方法。

我們可以再系統配置檔案的components專案裡修改系統應用元件的引數或配置新的應用元件。

cmodule並不負責應用元件例項的建立,而是由yii::createcomponent() 靜態方法來完成的。

createcomponent()的引數$config 可以是類名的字串或是儲存了類名和初始化引數的陣列。

應用元件的配置

應用元件的配置儲存在系統$config變數中(config/main.php裡)的components項裡:

$this->configure($config);

configure()函式的處理很簡單:

public function configure($config)

}setcomponents() 將'components』項裡的類名及初始化引數存放到 $_componentconfig裡:

應用元件的訪問

cmodule類過載了ccomponent的__get()方法,優先訪問應用元件物件。

public function __get($name)

hascomponent() 判斷$_components中是否已存在元件例項,或$_componentconfig中存在元件配置資訊。

public function hascomponent($id)

getcomponent() 判斷元件例項已經存在於$_components中,則直接返回物件。

否則根據$_componentconfig裡的元件配置資料呼叫 yii::createcomponent() 來建立元件,並將物件存入$_components中然後返回。

應用元件的建立

yii::createcomponent() 來完成應用元件的建立

public static function createcomponent($config)

else if(isset($config['class']))

else

throw new cexception(yii::t('yii','object configuration must be an array containing a "class" element.'));

if(!class_exists($type,false))

$type=yii::import($type,true);

if(($n=func_num_args())>1)

}else

$object=new $type;

foreach($config as $key=>$value)

$object->$key=$value;

return $object;}

#web

Linux USB驅動框架分析(三)

下面我們來分析一下usb skeleton的原始碼吧。這個範例程式可以在linux 2.6.17 drivers usb下找到,其他版本的核心程式原始碼可能有所不同,但相差不大。大家可以先找到原始碼看一看,先有個整體印象。之前已經提到,模組先要向核心註冊初始化跟銷毀函式 static int ini...

原創 Linux PCI驅動框架分析(三)

說明 kernel版本 4.14 arm64處理器 使用工具 source insight 3.5,visio 先回顧一下pcie的架構圖 那麼問題來了,platform device是在什麼時候建立的呢?那就不得不提到device tree裝置樹了。我們看看pcie host的裝置樹內容 pcie...

谷歌Volley網路框架分析。(三)訊息佇列

volley的訊息迴圈採用priorityblockingqueue來處理。在requestqueue中維護著乙個priorityblockingqueue佇列,所有的訊息都將新增到這個佇列當中,然後分配給networkdispatcher來處理這些訊息。priorityblockingqueue具...