應用程式
===========

應用程式是指請求處理中的執行上下文。它的主要任務是分析用戶請求並將其分派到合適的控制器中以作進一步處理。
它同時作為服務中心，維護應用程式級別的配置。有鑒於此，應用程式也叫做`前端控制器`。

應用程式由 [入口腳本](/doc/guide/basics.entry) 實體化為一個獨立的物件。這個獨立的應用程式可以在任何地方通過
 [Yii::app()|YiiBase::app] 存取。


應用程式配置
-------------------------

預設情況下，應用程式是一個  [CWebApplication] 的實體。要自定它，我們通常需要提供一個設定檔
（或陣列） 以建立應用程式實體時初始化的屬性值。自定應用程式的另一種方式是繼承 [CWebApplication]。

配置是一個鍵值配對陣列。每個鍵代表應用程式實體中某屬性的名字，每個值即相應屬性的初始值。
例如，如下的配置設定了應用程式的 [name|CApplication::name] 和
[defaultController|CWebApplication::defaultController] 屬性。

~~~
[php]
array(
	'name'=>'Yii Framework',
	'defaultController'=>'site',
)
~~~

我們通常在一個單獨的 PHP 腳本（e.g.`protected/config/main.php`）中保存這些配置。在腳本中，
我們通過以下方式返回此配置陣列：

~~~
[php]
return array(...);
~~~

要使用此配置，我們將設定檔的名字作為參數傳遞給應用程式的建構器，或像下面這樣傳遞到 [Yii::createWebApplication()]
。這通常在 [入口腳本](/doc/guide/basics.entry) 中完成：

~~~
[php]
$app=Yii::createWebApplication($configFile);
~~~

> Tip|提示: 如果應用程式配置非常複雜，我們可以把它分割為若干個文件，每個文件返回配置陣列中的一部分。
然後，在主設定檔中，我們調用 PHP 的 `include()` 包含其餘的設定檔並把它們合併為一個完整的配置數組。


應用程式基礎目錄
--------------------------

應用程式根目錄指包含了所有安全性敏感的 PHP 腳本和資料的根目錄。預設狀態下，它是一個位於含有入口腳本目錄的名為
`protected` 的子目錄。它可以通過設置 [application configuration](/doc/guide/basics.application#application-configuration)
中的 [basePath|CWebApplication::basePath] 屬性自定。

在應用程式基礎目錄下的內容應該保護起來防止網站訪客直接存取。對於 [Apache HTTP
伺服器](http://httpd.apache.org/), 這可以通過在根目錄中放置一個 `.htaccess`
文件簡單的實現。 `.htaccess` 內容如下：

~~~
deny from all
~~~

應用程式元件
---------------------

應用程式的功能可以通過其靈活的元件結構輕易地自定或增強。應用程式管理了一系列應用程式元件，每個元件實現一特定功能。
例如，應用程式通過 [CUrlManager] 和 [CHttpRequest] 的幫助解析來自用戶的請求。

通過配置應用程式的 [components|CApplication::components] 屬性，
我們可以自定義應用程式中用到的任何元件類別及其屬性值。例如，我們可以配置應用程式的 [CMemCache] 元件，
這樣它就可以使用多個 memcache 伺服器實現快取：

~~~
[php]
array(
	......
	'components'=>array(
		......
		'cache'=>array(
			'class'=>'CMemCache',
			'servers'=>array(
				array('host'=>'server1', 'port'=>11211, 'weight'=>60),
				array('host'=>'server2', 'port'=>11211, 'weight'=>40),
			),
		),
	),
)
~~~

如上所示，我們在 `components` 陣列中增加了 `cache` 元素。`cache` 元素表示此元件的類別是 `CMemCache`,
他的 `servers` 屬性應依此初始化。

要訪問一個應用程式元件，使用 `Yii::app()->ComponentID` ，其中的 `ComponentID` 是指元件的ID（例如 `Yii::app()->cache`）。

應用程式的元件可以通過在其配置中設置 `enabled` 為 false 禁用。當我們存取被禁用的元件時將返回 Null。

> Tip|提示: 預設情況下，應用程式元件會按需建立。這意味著一個應用程式的元件如果沒有在一個用戶請求中被存取，它可能根本不被建立。
因此，如果一個應用程式配置了很多元件，其總體性能可能並不會下降。有的應用程式元件 (例如 [CLogRouter]) 可能需要在無論它們是否被存取的情況下都要被建立。
要實現這個，需將其ID列在應用程式的 [preload|CApplication::preload] 屬性裡。

核心應用程式元件
---------------------------

Yii 預定義了一系列核心應用程式元件，提供常見 Web 應用程式中所用的功能。例如，
[request|CWebApplication::request] 元件用於解析用戶請求並提供例如 URL，cookie 等訊息。
通過配置這些核心元件的屬性，我們可以在幾乎所有 Yii 的預設行為。

下面我們列出了由 [CWebApplication] 預定義的核心元件。

   - [assetManager|CWebApplication::assetManager]: [CAssetManager] -
管理私有資源文件的發佈。

   - [authManager|CWebApplication::authManager]: [CAuthManager] - 管理角色的存取控制 (RBAC).

   - [cache|CApplication::cache]: [CCache] - 提供資料快取功能。注意，你必須指定實際的類別（例如[CMemCache], [CDbCache]）。
否則，當你存取此元件時將返回 NULL。

   - [clientScript|CWebApplication::clientScript]: [CClientScript] -
管理客戶端腳本 (javascripts 和 CSS).

   - [coreMessages|CApplication::coreMessages]: [CPhpMessageSource] -
提供 Yii 框架用到的核心訊息的翻譯。

   - [db|CApplication::db]: [CDbConnection] - 提供資料庫連接。注意，使用此元件你必須配置其
[connectionString|CDbConnection::connectionString] 屬性。

   - [errorHandler|CApplication::errorHandler]: [CErrorHandler] - 處理未擷取的 PHP 錯誤和異常。

   - [format|CApplication::format]: [CFormatter] - 正規畫數值顯示。此功能從版本 1.1.0 起開始提供。

   - [messages|CApplication::messages]: [CPhpMessageSource] - 提供Yii應用程式中使用的訊息翻譯。

   - [request|CWebApplication::request]: [CHttpRequest] - 提供關於用戶請求的訊息。

   - [securityManager|CApplication::securityManager]: [CSecurityManager] -
提供安全相關的服務，例如散列，加密。

   - [session|CWebApplication::session]: [CHttpSession] - 提供 session 相關的功能。

   - [statePersister|CApplication::statePersister]: [CStatePersister] - 提供全域狀態持續的方法。

   - [urlManager|CWebApplication::urlManager]: [CUrlManager] - 提供 URL 解析和建立相關功能

   - [user|CWebApplication::user]: [CWebUser] - 提供當前用戶的識別訊息。

   - [themeManager|CWebApplication::themeManager]: [CThemeManager] - 管理主題。


應用程式的生命週期
----------------------

當處理用戶請求時，應用程式將經歷如下聲明週期：

   0. 通過 [CApplication::preinit()] 預初始化應用程式；

   1. 設置類別的自動載入器和錯誤處理；

   2. 註冊核心類別元件；

   3. 載入應用程式配置；

   4. 通過 [CApplication::init()] 初始化應用程式:
      - 註冊應用程式行為；
	   - 載入靜態應用程式元件；

   5. 觸發 [onBeginRequest|CApplication::onBeginRequest] 事件；

   6. 處理用戶請求：
	   - 解析用戶請求；
	   - 建立控制器；
	   - 運行控制器；

   7. 觸發 [onEndRequest|CApplication::onEndRequest] 事件。

<div class="revision">$Id$</div>