配置


配置

在 Yii 中,創建新對象和初始化已存在對象時廣泛使用配置。配置通常包含被創建對象的類名和一組將要賦值給對象屬性的初始值。還可能包含一組將被附加到對象事件上的句柄。和一組將被附加到對象上的行爲

以下代碼中的配置被用來創建並初始化一個數據庫連接:

  1. $config = [ 
  2.     'class' => 'yii\\db\\Connection', 
  3.     'dsn' => 'mysql:host=127.0.0.1;dbname=demo', 
  4.     'username' => 'root', 
  5.     'password' => '', 
  6.     'charset' => 'utf8', 
  7. ]; 
  8.  
  9. $db = Yii::createObject($config);

[[Yii::createObject()]] 方法接受一個配置並根據配置中指定的類名創建對象。對象實例化後,剩餘的參數被用來初始化對象的屬性,事件處理和行爲。

對於已存在的對象,可以使用 [[Yii::configure()]] 方法根據配置去初始化其屬性,就像這樣:

  1. Yii::configure($object, $config);

請注意,如果配置一個已存在的對象,那麼配置數組中不應該包含指定類名的 class 元素。

配置的格式

一個配置的格式可以描述爲以下形式:

  1.     'class' => 'ClassName', 
  2.     'propertyName' => 'propertyValue', 
  3.     'on eventName' => $eventHandler, 
  4.     'as behaviorName' => $behaviorConfig, 
  5. ]

其中

  • class 元素指定了將要創建的對象的完全限定類名。
  • propertyName 元素指定了對象屬性的初始值。鍵名是屬性名,值是該屬性對應的初始值。只有公共成員變量以及通過 getter/setter 定義的屬性可以被配置。
  • on eventName 元素指定了附加到對象事件上的句柄是什麼。請注意,數組的鍵名由 on 前綴加事件名組成。請參考事件章節瞭解事件句柄格式。
  • as behaviorName 元素指定了附加到對象的行爲。請注意,數組的鍵名由 as 前綴加行爲名組成。$behaviorConfig 表示創建行爲的配置信息,格式與我們現在總體敘述的配置格式一樣。

下面是一個配置了初始化屬性值,事件句柄和行爲的示例:

  1.     'class' => 'app\\components\\SearchEngine', 
  2.     'apiKey' => 'xxxxxxxx', 
  3.     'on search' => function ($event) { 
  4.         Yii::info("搜索的關鍵詞: " . $event->keyword); 
  5.     }, 
  6.     'as indexer' => [ 
  7.         'class' => 'app\\components\\IndexerBehavior', 
  8.         // ... 初始化屬性值 ... 
  9.     ], 
  10. ]

使用配置

Yii 中的配置可以用在很多場景。本章開頭我們展示瞭如何使用 [[Yii::creatObject()]] 根據配置信息創建對象。本小節將介紹配置的兩種主要用法 —— 配置應用與配置小部件。

應用的配置

應用的配置可能是最複雜的配置之一。因爲 [[yii\web\Application|application]] 類擁有很多可配置的屬性和事件。更重要的是它的 [[yii\web\Application::components|components]] 屬性可以接收配置數組並通過應用註冊爲組件。以下是一個針對基礎應用模板的應用配置概要:

  1. $config = [ 
  2.     'id' => 'basic', 
  3.     'basePath' => dirname(__DIR__), 
  4.     'extensions' => require(__DIR__ . '/../vendor/yiisoft/extensions.php'), 
  5.     'components' => [ 
  6.         'cache' => [ 
  7.             'class' => 'yii\\caching\\FileCache', 
  8.         ], 
  9.         'mailer' => [ 
  10.             'class' => 'yii\\swiftmailer\\Mailer', 
  11.         ], 
  12.         'log' => [ 
  13.             'class' => 'yii\\log\\Dispatcher', 
  14.             'traceLevel' => YII_DEBUG ? 3 : 0, 
  15.             'targets' => [ 
  16.                 [ 
  17.                     'class' => 'yii\\log\\FileTarget', 
  18.                 ], 
  19.             ], 
  20.         ], 
  21.         'db' => [ 
  22.             'class' => 'yii\\db\\Connection', 
  23.             'dsn' => 'mysql:host=localhost;dbname=stay2', 
  24.             'username' => 'root', 
  25.             'password' => '', 
  26.             'charset' => 'utf8', 
  27.         ], 
  28.     ], 
  29. ];

配置中沒有 class 鍵的原因是這段配置應用在下面的入口腳本中,類名已經指定了。

  1. (new yii\\web\\Application($config))->run();

更多關於應用 components 屬性配置的信息可以查閱應用以及服務定位器章節。

小部件的配置

使用小部件時,常常需要配置以便自定義其屬性。 [[yii\base\Widget::widget()]] 和 [[yii\base\Widget::beginWidget()]] 方法都可以用來創建小部件。它們可以接受配置數組:

  1. use yii\\widgets\\Menu; 
  2.  
  3. echo Menu::widget([ 
  4.     'activateItems' => false, 
  5.     'items' => [ 
  6.         ['label' => 'Home', 'url' => ['site/index']], 
  7.         ['label' => 'Products', 'url' => ['product/index']], 
  8.         ['label' => 'Login', 'url' => ['site/login'], 'visible' => Yii::$app->user->isGuest], 
  9.     ], 
  10. ]);

上述代碼創建了一個小部件 Menu 並將其 activateItems 屬性初始化爲 false。item 屬性也配置成了將要顯示的菜單條目。

請注意,代碼中已經給出了類名 yii\widgets\Menu',配置數組**不應該**再包含 class` 鍵。

配置文件

當配置的內容十分複雜,通用做法是將其存儲在一或多個 PHP 文件中,這些文件被稱爲配置文件。一個配置文件返回的是 PHP 數組。例如,像這樣把應用配置信息存儲在名爲 web.php 的文件中:

  1. return [ 
  2.     'id' => 'basic', 
  3.     'basePath' => dirname(__DIR__), 
  4.     'extensions' => require(__DIR__ . '/../vendor/yiisoft/extensions.php'), 
  5.     'components' => require(__DIR__ . '/components.php'), 
  6. ];

鑑於 components 配置也很複雜,上述代碼把它們存儲在單獨的 components.php 文件中,並且包含在web.php 裏。components.php 的內容如下:

  1. return [ 
  2.     'cache' => [ 
  3.         'class' => 'yii\\caching\\FileCache', 
  4.     ], 
  5.     'mailer' => [ 
  6.         'class' => 'yii\\swiftmailer\\Mailer', 
  7.     ], 
  8.     'log' => [ 
  9.         'class' => 'yii\\log\\Dispatcher', 
  10.         'traceLevel' => YII_DEBUG ? 3 : 0, 
  11.         'targets' => [ 
  12.             [ 
  13.                 'class' => 'yii\\log\\FileTarget', 
  14.             ], 
  15.         ], 
  16.     ], 
  17.     'db' => [ 
  18.         'class' => 'yii\\db\\Connection', 
  19.         'dsn' => 'mysql:host=localhost;dbname=stay2', 
  20.         'username' => 'root', 
  21.         'password' => '', 
  22.         'charset' => 'utf8', 
  23.     ], 
  24. ];

僅僅需要 「require」,就可以取得一個配置文件的配置內容,像這樣:

  1. $config = require('path/to/web.php'); 
  2. (new yii\\web\\Application($config))->run();

默認配置

[[Yii::createObject()]] 方法基於依賴注入容器實現。使用 [[Yii::creatObject()]] 創建對象時,可以附加一系列默認配置到指定類的任何實例。默認配置還可以在入口腳本中調用 Yii::$container->set() 來定義。

例如,如果你想自定義 [[yii\widgets\LinkPager]] 小部件,以便讓分頁器最多隻顯示 5 個翻頁按鈕(默認是 10 個),你可以用下述代碼實現:

  1. \\Yii::$container->set('yii\\widgets\\LinkPager', [ 
  2.     'maxButtonCount' => 5, 
  3. ]);

不使用默認配置的話,你就得在任何使用分頁器的地方,都配置 maxButtonCount 的值。

環境常量

配置經常要隨着應用運行的不同環境更改。例如在開發環境中,你可能使用名爲 mydb_dev 的數據庫,而生產環境則使用 mydb_prod 數據庫。爲了便於切換使用環境,Yii 提供了一個定義在入口腳本中的 YII_ENV 常量。如下:

  1. defined('YII_ENV') or define('YII_ENV', 'dev');

你可以把 YII_ENV 定義成以下任何一種值:

  • prod:生產環境。常量 YII_ENV_PROD 將被看作 true。如果你沒修改過,這就是 YII_ENV 的默認值。
  • dev:開發環境。常量 YII_ENV_DEV 將被看作 true。
  • test:測試環境。常量 YII_ENV_TEST 將被看作 true。

有了這些環境常量,你就可以根據當下應用運行環境的不同,進行差異化配置。例如,應用可以包含下述代碼只在開發環境中開啓調試工具

  1. $config = [...]; 
  2.  
  3. if (YII_ENV_DEV) { 
  4.     // 根據 `dev` 環境進行的配置調整 
  5.     $config['bootstrap'][] = 'debug'; 
  6.     $config['modules']['debug'] = 'yii\\debug\\Module'; 
  7.  
  8. return $config;