yiiframework 簡介 五

http://vmee.org/yiiframework%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E5%8D%81%E4%B8%89%E4%B9%8B%E7%BC%93%E5%AD%98

 

 

十三、緩存
緩存是用於提升網站性能的一種即簡單又有效的途徑。
通過存儲相對靜態的數據至緩存以備所需,我們可以省去生成這些數據的時間。
在 Yii 中使用緩存主要包括配置和訪問緩存組件。
如下的應用配置指定了一個使用兩臺緩存服務器的 memcache 緩存組件:
array(
......
'components'=>array(
......
'cache'=>array(
'class'=>'system.caching.CMemCache',
'servers'=>array(
array('host'=>'server1', 'port'=>11211, 'weight'=>60),
array('host'=>'server2', 'port'=>11211, 'weight'=>40),
),
),
),
);
程序運行的時候可以通過 Yii::app()->cache 來訪問緩存組件。
Yii
提供多種緩存組件以便在不同的媒介上存儲緩存數據。
比如 CMemCache 組件封裝了 PHP memcache
擴展,它使用內存作爲存儲緩存的媒介;CApcCache 組件封裝了 PHP APC 擴展;CDbCache
組件在數據庫裏存儲緩存數據。下面是各種緩存組件的簡要說明:
CMemCache: 使用 PHP memcache 擴展。
CApcCache: 使用 PHP APC 擴展。
CXCache: 使用 PHP XCache 擴展。
CDbCache: 使用一張數據庫表來存儲緩存數據。
它默認在運行時目錄建立並使用一個 SQLite3 數據庫,你可以通過設置 connectionID 屬性顯式地指定一個數據庫給它使用。
提示: 因爲所有這些緩存組件都從同一個基礎類 CCache 擴展而來,不需要修改使用緩存的代碼即可在不同的緩存組件之間切換。
緩存可以在不同的級別使用。在最低級別,我們使用緩存來存儲單個數據,比如一個變量,我們把它叫做 數據緩存。
往上一級,我們緩存一個由視圖腳本生成的頁面片斷。在最高級別,我們存儲整個頁面以便需要的時候直接從緩存讀取。
接下來我們將闡述如何在這些級別上使用緩存。
注意: 按定義來講,緩存是一個不穩定的存儲媒介,它不保證緩存一定存在——不管該緩存是否過期。
所以,不要使用緩存進行持久存儲(比如,不要使用緩存來存儲 SESSION 數據)。
一、數據緩存
數據緩存也就是在緩存中存儲一些 PHP 變量,過一會再取出來。緩存基礎類 CCache 提供了兩個最常用的方法:set() 和 get()。
 
要在緩存中存儲變量 $value,我們選擇一個唯一 ID 並調用 set() 來存儲它:
 
Yii::app()->cache->set($id, $value);
 
被緩存的數據會一直保留在緩存中,直到因一些緩存策略而被刪除(比如緩存空間滿了,刪除最舊的數據)。要改變這一行爲,我們還可以在調用 set() 時加一個過期參數,這樣數據過一段時間就會自動從緩存中清除。
 
// 在緩存中保留該值最多 30 秒
Yii::app()->cache->set($id, $value, 30);
 
當我們稍後需要訪問該變量時(不管是不是同一 Web 請求),我們調用 get() (傳入 ID)來從緩存中獲取它。如果返回值爲 false,說明該緩存不可用,需要我們重新生成它。
 
$value=Yii::app()->cache->get($id);
if($value===false)
{
// 因爲在緩存中沒找到,重新生成 $value
// 再緩存一下以備下次使用
// Yii::app()->cache->set($id,$value);
}
爲一個要緩存的變量選擇 ID 時,確保該 ID 在應用中是唯一的。
不必保證 ID 在跨應用的情況下保證唯一,因爲緩存組件有足夠的智能來區分不同應用的緩存 ID。
要從緩存中刪除一個緩存值,調用 delete();要清空所有緩存,調用 flush()。
調用 flush() 時要非常小心,因爲它會把其它應用的緩存也清空。
提示: 因爲 CCache 實現了 ArrayAccess 接口,可以像數組一樣使用緩存組件。例如:
$cache=Yii::app()->cache;
$cache['var1']=$value1;  // 相當於: $cache->set('var1',$value1);
$value2=$cache['var2'];  // 相當於: $value2=$cache->get('var2');
 
緩存依賴除了過期設置,緩存數據還會因某些依賴條件發生改變而失效。
如果我們緩存了某文件的內容,而該文件後來又被更新了,我們應該讓緩存中的拷貝失效,從文件中讀取最新內容(而不是從緩存)。
我們把一個依賴關係表現爲一個 CCacheDependency 或它的子類的實例,調用 set() 的時候把依賴實例和要緩存的數據一起傳入。
// 緩存將在 30 秒後過期
// 也可能因依賴的文件有更新而更快失效
Yii::app()->cache->set($id, $value, 30, new CFileCacheDependency('FileName'));
如果我們現在調用 get() 從緩存中獲取 $value,緩存組件將檢查依賴條件。如果有變,我們會得到 false 值——數據需要重新生成。
下面是可用的緩存依賴的簡要說明:
CFileCacheDependency: 該依賴因文件的最近修改時間發生改變而改變。
CDirectoryCacheDependency: 該依賴因目錄(或其子目錄)下的任何文件發生改變而改變。
CDbCacheDependency: 該依賴因指定的 SQL 語句的查詢結果發生改變而改變。
CGlobalStateCacheDependency: 該依賴因指定的全局狀態值發生改變而改變。
全局狀態是應用中跨請求、跨 SESSION 的持久變量,它由 CApplication::setGlobalState() 來定義。
CChainedCacheDependency: 該依賴因依賴鏈中的任何一環發生改變而改變。
二、片段緩存(Fragment Caching)
片段緩存指緩存網頁某片段。
例如,如果一個頁面在表中顯示每年的銷售摘要,我們可以存儲此表在緩存中,減少每次請求需要重新產生的時間。
要使用片段緩存,在控制器視圖腳本中調用CController::beginCache() 和CController::endCache() 。
這兩種方法開始和結束包括的頁面內容將被緩存。
類似data caching ,我們需要一個編號,識別被緩存的片段。
...別的HTML內容...
beginCache($id)) { ?>
...被緩存的內容...
endCache(); } ?>
...別的HTML內容...
在上面的,如果beginCache() 返回false,緩存的內容將此地方自動插入; 否則,在if語句內的內容將被執行並在endCache()觸發時緩存。
1. 緩存選項(Caching Options)
當調用beginCache(),可以提供一個數組由緩存選項組成的作爲第二個參數,以自定義片段緩存。
事實上爲了方便,beginCache() 和 endCache()方法是 COutputCache widget的包裝。
因此COutputCache的所有屬性都可以在緩存選項中初始化。
2. 有效期(Duration)
也許是最常見的選項是duration,指定了內容在緩存中多久有效。和CCache::set()過期參數有點類似。下面的代碼緩存內容片段最多一小時:
...其他HTML內容...
beginCache($id, array('duration'=>3600))) { ?>
...被緩存的內容...
endCache(); } ?>
...其他HTML內容...
如果我們不設定期限,它將默認爲60 ,這意味着60秒後緩存內容將無效。
3. 依賴(Dependency)
像data caching ,內容片段被緩存也可以有依賴。
例如,文章的內容被顯示取決於文章是否被修改。
要指定一個依賴,我們建立了dependency選項,可以是一個實現ICacheDependency的對象或可用於生成依賴對象的配置數組。
下面的代碼指定片段內容取決lastModified 列的值是否變化:
...其他HTML內容...
beginCache($id, array('dependency'=>array(
'class'=>'system.caching.dependencies.CDbCacheDependency',
'sql'=>'SELECT MAX(lastModified) FROM Post')))) { ?>
...被緩存的內容...
endCache(); } ?>
...其他HTML內容...
4. 變化(Variation)
緩存的內容可根據一些參數變化。
例如,每個人的檔案都不一樣。緩存的檔案內容將根據每個人ID變化。這意味着,當調用beginCache()時將用不同的ID。
COutputCache內置了這一特徵,程序員不需要編寫根據ID變動內容的模式。以下是摘要。
varyByRoute: 設置此選項爲true ,緩存的內容將根據route變化。因此,每個控制器和行動的組合將有一個單獨的緩存內容。
varyBySession: 設置此選項爲true ,緩存的內容將根據session ID變化。因此,每個用戶會話可能會看到由緩存提供的不同內容。
varyByParam:
設置此選項的數組裏的名字,緩存的內容將根據GET參數的值變動。例如,如果一個頁面顯示文章的內容根據id的GET參數,我們可以指定
varyByParam爲array('id'),以使我們能夠緩存每篇文章內容。如果沒有這樣的變化,我們只能能夠緩存某一文章。
5. 請求類型(Request Types)
有時候,我們希望片段緩存只對某些類型的請求啓用。
例如,對於某張網頁上顯示錶單,我們只想要緩存initially requested表單(通過GET請求)。
任何隨後顯示(通過POST請求)的表單將不被緩存,因爲表單可能包含用戶輸入。
要做到這一點,我們可以指定
requestTypes 選項:
...其他HTML內容...
beginCache($id, array('requestTypes'=>array('GET')))) { ?>
...被緩存的內容...
endCache(); } ?>
...其他HTML內容...
6. 嵌套緩存(Nested Caching)
片段緩存可以嵌套。就是說一個緩存片段附在一個更大的片段緩存裏。
例如,意見緩存在內部片段緩存,而且它們一起在外部緩存中在文章內容裏緩存。
...其他HTML內容...
beginCache($id1)) { ?>
...外部被緩存內容...
beginCache($id2)) { ?>
...內部被緩存內容...
endCache(); } ?>
...外部被緩存內容...
endCache(); } ?>
...其他HTML內容...
嵌套緩存可以設定不同的緩存選項。
例如,
在上面的例子中內部緩存和外部緩存可以設置時間長短不同的持續值。
當數據存儲在外部緩存無效,內部緩存仍然可以提供有效的內部片段。
然而,反之就不行了。如果外部緩存包含有效的數據, 它會永遠保持緩存副本,即使內容中的內部緩存已經過期。
三、頁面緩存
頁面緩存指的是緩存整個頁面的內容。頁面緩存可以發生在不同的地方。
例如,通過選擇適當的頁面頭,客戶端的瀏覽器可能會緩存網頁瀏覽有限時間。 
Web應用程序本身也可以在緩存中存儲網頁內容。 在本節中,我們側重於後一種辦法。
頁面緩存可以被看作是 片段緩存 (/doc/guide/caching.fragment)一個特殊情況。
由於網頁內容是往往通過應用佈局來生成,如果我們只是簡單的在佈局中調用 beginCache()和endCache(),將無法正常工作。
這是因爲佈局在CController::render()方法裏的加載是在頁面內容產生之後。
緩存整個頁面,我們應該跳過產生網頁內容的動作執行。
我們可以使用 COutputCache 作爲動作 過濾器 (/doc/guide/basics.controller#filter)來完成這一任務。
下面的代碼演示如何配置緩存過濾器:
public function filters()
{
return array(
array(
'system.web.widgets.COutputCache',
'duration'=>100,
'varyByParam'=>array('id'),
),
);
}
上述過濾器配置會使過濾器適用於控制器中的所有行動。我們可能會限制它在一個或幾個行動通過使用插件操作器。更多的細節中可以看過濾器(/doc/guide/basics.controller#filter) 。
提示:我們可以使用 COutputCache 作爲一個過濾器,因爲它從CFilterWidget繼承過來
,這意味着它是一個工具(widget)和一個過濾器。
事實上, widge的工作方式和過濾器非常相似:工具widget(過濾器filter)是在action動作裏的內容執行前執行,在執行後結束。
四、動態內容(Dynamic Content)
當使用fragment caching或page caching,我們常常遇到的這樣的情況整個部分的輸出除了個別地方都是靜態的。
例如,幫助頁可能會顯示靜態的幫助信息,而用戶名稱顯示的是當前用戶的。
解決這個問題,我們可以根據用戶名匹配緩存內容,但是這將是我們寶貴空間一個巨大的浪費,因爲緩存除了用戶名其他大部分內容是相同的。
我們還可以把網頁切成幾個片段並分別緩存,但這種情況會使頁面和代碼變得非常複雜。
更好的方法是使用由 CController 提供的動態內容dynamic content功能 。
動態內容是指片段輸出即使是在片段緩存包括的內容中也不會被緩存。
即使是包括的內容是從緩存中取出,爲了使動態內容在所有時間是動態的,每次都得重新生成。
出於這個原因,我們要求動態內容通過一些方法或函數生成。
調用CController::renderDynamic()在你想的地方插入動態內容。
...別的HTML內容...
beginCache($id)) { ?>
...被緩存的片段內容...
renderDynamic($callback); ?>
...被緩存的片段內容...
endCache(); } ?>
...別的HTML內容...
在上面的, $callback指的是有效的PHP回調。
它可以是指向當前控制器類的方法或者全局函數的字符串名。
它也可以是一個數組名指向一個類的方法。其他任何的參數,將傳遞到renderDynamic()方法中。回調將返回動態內容而不是僅僅顯示它。

 

 

 

 

http://vmee.org/yiiframework%E5%85%A5%E9%97%A8%E6%95%99%E7%A8%8B%E5%8D%81%E5%9B%9B%E4%B9%8B%E6%89%A9%E5%B1%95

 

 

十四、擴展Yii
在開發中擴展Yii是一個很常見的行爲.例如,當你寫一個新的控制器時,你通過繼承 CController  類擴展了Yii; 
當你編寫一個新的組件時,
你正在繼承 CWidget 或者一個已存在的組件類.如果擴展代碼是由第三方開發者爲了複用而設計的,我們則稱之爲extension(擴展)。
一個擴展通常是爲了一個單一的目的服務的.在 Yii 中,他可以按照如下分類:
* 應用的部件
* 組件
* 控制器
* 動作
* 過濾器
* 控制檯命令
* 校驗器: 校驗器是一個繼承自 CValidator 類的部件。
* 輔助器: 輔助器是一個只具有靜態方法的類.它類似於使用類名作爲命名空間的全局函數。
* 模塊: 模塊是一個有着若干個類文件和相應特長文件的包.一個模塊通常更高級,比一個單一的部件具備更先進的功能.例如我們可以擁有一個具備整套用戶管理功能的模塊。
擴展也可以是不屬於上述分類中的任何一個的部件。事實上,Yii 是設計得很謹慎的,以至於幾乎它的每段代碼都可以被擴展和訂製以適用於特定需求。
一、使用擴展
使用擴展通常包含了以下三步:
1. 從 Yii 的 擴展庫 下載擴展。
2. 解壓到 應用程序的基目錄 的子目錄 extensions/xyz 下,這裏的 xyz 是擴展的名稱。
3. 導入, 配置和使用擴展。
每個擴展都有一個所有擴展中唯一的名稱標識。把一個擴展命名爲 xyz ,我們也可以使用路徑別名定位到包含了 xyz 所有文件的基目錄。
不同的擴展有着不同的導入,配置,使用要求.以下是我們通常會用到擴展的場景,按照他們在 概述 中的描述分類。
1、應用的部件
使用 應用的部件, 首先我們需要添加一個新條目到 應用配置 的 components 屬性, 如下所示:
return array(
// 'preload'=>array('xyz',...),
'components'=>array(
'xyz'=>array(
'class'=>'application.extensions.xyz.XyzClass',
'property1'=>'value1',
'property2'=>'value2',
),
// 其他部件配置
),
);
然後,我們可以在任何地方通過使用 Yii::app()->xyz 來訪問部件.部件將會被 惰性創建(就是,僅當它第一次被訪問時創建.) , 除非我們把它配置到 preload 屬性裏。
2、組件
組件 主要用在 視圖 裏.假設組件類 XyzClass 屬於 xyz 擴展,我們可以如下在視圖中使用它:
// 組件不需要主體內容
widget('application.extensions.xyz.XyzClass', array(
'property1'=>'value1',
'property2'=>'value2')); ?>
 
// 組件可以包含主體內容
beginWidget('application.extensions.xyz.XyzClass', array(
'property1'=>'value1',
'property2'=>'value2')); ?>
 
...組件的主體內容...
 
endWidget(); ?>
 
3、動作
動作 被 控制器 用於響應指定的用戶請求.假設動作的類 XyzClass 屬於 xyz 擴展,我們可以在我們的控制器類裏重寫 CController::actions 方法來使用它:
class TestController extends CController
{
public function actions()
{
return array(
'xyz'=>array(
'class'=>'application.extensions.xyz.XyzClass',
'property1'=>'value1',
'property2'=>'value2',
),
// 其他動作
);
}
}
然後,我們可以通過 路由 test/xyz 來訪問。
4、過濾器
過濾器 也被 控制器 使用。過濾器主要用於當其被 動作 掛起時預處理,提交處理用戶請求。
假設過濾器的類 XyzClass 屬於 xyz 擴展,我們可以在我們的控制器類裏重寫 CController::filters 方法來使用它:
class TestController extends CController
{
public function filters()
{
return array(
array(
'application.extensions.xyz.XyzClass',
'property1'=>'value1',
'property2'=>'value2',
),
// 其他過濾器
);
}
}
在上述代碼中,我們可以在數組的第一個元素離使用加號或者減號操作符來限定過濾器只在那些動作中生效。更多信息,請參照文檔的 CController。
5、控制器
控制器 提供了一套可以被用戶請求的動作。我們需要在 應用配置 裏設置 CWebApplication::controllerMap 屬性,才能在控制器裏使用擴展:
return array(
'controllerMap'=>array(
'xyz'=>array(
'class'=>'application.extensions.xyz.XyzClass',
'property1'=>'value1',
'property2'=>'value2',
),
// 其他控制器
),
);
然後, 一個在控制裏的 a 行爲就可以通過 路由 xyz/a 來訪問了。
6、校驗器
校驗器主要用在 模型類 (繼承自 CFormModel 或者 CActiveRecord) 中.假設校驗器類 XyzClass 屬於 xyz 擴展,我們可以在我們的模型類中通過 CModel::rules 重寫 CModel::rules 來使用它:
class MyModel extends CActiveRecord // or CFormModel
{
public function rules()
{
return array(
array(
'attr1, attr2',
'application.extensions.xyz.XyzClass',
'property1'=>'value1',
'property2'=>'value2',
),
// 其他校驗規則
);
}
}
7、控制檯命令
控制檯命令擴展通常使用一個額外的命令來增強 yiic 的功能.假設命令控制檯 XyzClass 屬於 xyz 擴展,我們可以通過設定控制檯應用的配置來使用它:
return array(
'commandMap'=>array(
'xyz'=>array(
'class'=>'application.extensions.xyz.XyzClass',
'property1'=>'value1',
'property2'=>'value2',
),
// 其他命令
),
);
 
然後,我們就能使用配備了額外命令 xyz 的 yiic 工具了。
注意: 控制檯應用通常使用了一個不同於 Web 應用的配置文件.如果使用了 yiic webapp 命令創建了一個應用,這樣的話,控制檯應用的
protected/yiic 的配置文件就是 protected/config/console.php 了,而Web應用的配置文件 則是protected/config/main.php。
8、模塊
模塊通常由多個類文件組成,且往往綜合上述擴展類型。因此,你應該按照和以下一致的指令來使用模塊。
9、通用部件
使用一個通用 部件, 我們首先需要通過使用
Yii::import('application.extensions.xyz.XyzClass');
來包含它的類文件。然後,我們既可以創建一個類的實例,配置它的屬性,也可以調用它的方法。我們還可以創建一個新的子類來擴展它。
二、創建擴展
由於擴展意味着是第三方開發者使用,需要一些額外的努力去創建它。以下是一些一般性的指導原則:
*擴展最好是自己自足。也就是說,其外部的依賴應是最少的。如果用戶的擴展需要安裝額外的軟件包,類或資源檔案,這將是一個頭疼的問題。
*文件屬於同一個擴展的,應組織在同一目錄下,目錄名用擴展名稱。
*擴展裏面的類應使用一些單詞字母前綴,以避免與其他擴展命名衝突。
*擴展應該提供詳細的安裝和API文檔。這將減少其他開發員使用擴展時花費的時間和精力。
*擴展應該用適當的許可。如果您想您的擴展能在開源和閉源項目中使用,你可以考慮使用許可證,如BSD的,麻省理工學院等,但不是GPL的,因爲它要求其衍生的代碼是開源的。
在下面,我們根據 overview中所描述的分類,描述如何創建一個新的擴展。當您要創建一個主要用於在您自己項目的component部件,這些描述也適用。
1、Application Component(應用部件)
一個application component 應實現接口IApplicationComponent或繼承CApplicationComponent。
主要需要實現的方法是 IApplicationComponent::init,部件在此執行一些初始化工作。
此方法在部件創建和屬性值(在application configuration裏指定的 )被賦值後調用。
默認情況下,一個應用程序部件創建和初始化,只有當它首次訪問期間要求處理。
如果一個應用程序部件需要在應用程序實例被創建後創建,它應要求用戶在CApplication::preload 的屬性中列出他的編號。
2、Widget(小工具)
widget應繼承CWidget或其子類。 A widget should extend from CWidget or its child classes.
最簡單的方式建立一個新的小工具是繼承一個現成的小工具和重載它的方法或改變其默認的屬性值。
例如,如果您想爲CTabView使用更好的CSS樣式,您可以配置其CTabView::cssFile屬性,當使用的小工具時。
您還可以繼承CTabView如下,讓您在使用小工具時,不再需要配置屬性。
class MyTabView extends CTabView
{
public function init()
{
if($this->cssFile===null)
{
$file=dirname(__FILE__).DIRECTORY_SEPARATOR.'tabview.css';
$this->cssFile=Yii::app()->getAssetManager()->publish($file);
}
parent::init();
}
}
在上面的,我們重載CWidget::init方法和指定CTabView::cssFile的
URL到我們的新的默認CSS樣式如果此屬性未設置時。我們把新的CSS樣式文件和MyTabView類文件放在相同的目錄下,以便他們能夠封裝成擴展。
由於CSS樣式文件不是通過Web訪問,我們需要發佈作爲一項asset資源。
要從零開始創建一個新的小工具,我們主要是需要實現兩個方
法:CWidget::init 和CWidget::run。第一種方法是當我們在視圖中使用 $this->beginWidget
插入一個小工具時被調用,第二種方法在$this->endWidget被調用時調用。如果我們想在這兩個方法調用之間捕捉和處理顯示的內容,我們
可以開始output buffering在CWidget::init 和在CWidget::run中回收緩衝輸出作進一步處理。 
If we want to capture and process the content displayed between these two method invocations, we can start output buffering in CWidget::init and
retrieve the buffered output in CWidget::run for further processing.
 
在網頁中使用的小工具,小工具往往包括CSS,java script或其他資源文件。
我們叫這些文件assets,因爲他們和小工具類在一起,而且通常Web用戶無法訪問。
爲了使這些檔案通過Web訪問,我們需要用CWebApplication::assetManager發佈他們,例如上述代碼段所
示。此外,如果我們想包括CSS或java script文件在當前的網頁,我們需要使用CClientScript註冊 :
class MyWidget extends CWidget
{
protected function registerClientScript()
{
// ...publish CSS or java script file here...
$cs=Yii::app()->clientScript;
$cs->registerCssFile($cssFile);
$cs->registerScriptFile($jsFile);
}
}
小工具也可能有自己的視圖文件。如果是這樣,創建一個目錄命名views在包括小工具類文件的目錄下,並把所有的視圖文件放裏面。在小工具類中使用$this->render('ViewName') 來render渲染小工具視圖,類似於我們在控制器裏做。
3、Action(動作)
action應繼承CAction或者其子類。action要實現的主要方法是IAction::run 。
4、Filter(過濾器)
filter應繼承CFilter 或者其子類。filter要實現的主要方法是CFilter::preFilter和CFilter::postFilter。前者是在action之前被執行,而後者是在之後。
class MyFilter extends CFilter
{
protected function preFilter($filterChain)
{
// logic being applied before the action is executed
return true; // false if the action should not be executed
}
 
protected function postFilter($filterChain)
{
// logic being applied after the action is executed
}
}
參數$filterChain的類型是CFilterChain,其包含當前被filter的action的相關信息。
5、Controller(控制器)
controller
要作爲擴展需繼承CExtController,而不是 CController。主要的原因是因爲CController 認定控制器視圖文件位於application.views.ControllerID 下,
而CExtController認定視圖文件在views目錄下,也是包含控制器類目錄的一個子目錄。因此,很容易重新分配控制器,因爲它的視圖文件和控制類是在一起的。
6、Validator(驗證)
Validator需繼承CValidator和實現CValidator::validateAttribute方法。
class MyValidator extends CValidator
{
protected function validateAttribute($model,$attribute)
{
$value=$model->$attribute;
if($value has error)
$model->addError($attribute,$errorMessage);
}
}
7、Console Command(控制檯命令)
console command 應繼承CConsoleCommand和實現CConsoleCommand::run方法。 或者,我們可以重載CConsoleCommand::getHelp來提供一些更好的有關幫助命令。
class MyCommand extends CConsoleCommand
{
public function run($args)
{
// $args gives an array of the command-line arguments for this command
}
 
public function getHelp()
{
return 'Usage: how to use this command';
}
}
8、Module(模塊)
請參閱modules一節中關於就如何創建一個模塊。
一般準則制訂一個模塊,它應該是獨立的。模塊所使用的資源文件(如CSS , java script ,圖片),應該和模塊一起分發。還有模塊應發佈它們,以便可以Web訪問它們 。
9、Generic Component(通用組件)
開發一個通用組件擴展類似寫一個類。還有,該組件還應該自足,以便它可以很容易地被其他開發者使用。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章