Yii 基於 Prado 的元件架構,元件 是可重用功能單元,掛載於應用實例,支援懶性載入與設定管理。
<?php
// protected/components/Utilities.php
class Utilities extends CApplicationComponent {
// 公開屬性:可在 main.php 設定
public $apiKey = '';
public $timeout = 30;
// 初始化:應用啟動時自動呼叫(若啟用 preload)
public function init() {
parent::init();
// 驗證必要設定
if (empty($this->apiKey)) {
throw new CException('Utilities.apiKey 未設定');
}
}
// 公開靜態方法:工具函數風格
public static function formatPrice($amount, $currency = 'TWD') {
return $currency . number_format($amount, 0);
}
// 實例方法:需透過 Yii::app()->utilities 呼叫
public function callApi($endpoint, $params = []) {
// 使用 $this->apiKey, $this->timeout
// ...
}
}
return [
'components' => [
'utilities' => [
'class' => 'application.components.Utilities',
'apiKey' => 'your-secret-key',
'timeout' => 15,
],
// 其他元件...
],
// 預載入:應用啟動時即實例化
'preload' => ['log', 'utilities'],
];
// 靜態方法(無狀態工具)
echo Utilities::formatPrice(12345); // TWD12,345
// 實例方法(有狀態服務)
$response = Yii::app()->utilities->callApi('/users', ['limit' => 10]);
// 存取元件屬性
$key = Yii::app()->utilities->apiKey;
class PaymentComponent extends CApplicationComponent {
public function behaviors() {
return [
'logging' => [
'class' => 'application.behaviors.LoggingBehavior',
'logLevel' => 'info',
],
];
}
public function charge($orderId, $amount) {
$this->onBeforeCharge(new CEvent($this, [
'orderId' => $orderId,
'amount' => $amount,
]));
// 扣款邏輯...
$this->onAfterCharge(new CEvent($this, [
'orderId' => $orderId,
'success' => true,
]));
}
// 事件定義
public function onBeforeCharge($event) { $this->raiseEvent('onBeforeCharge', $event); }
public function onAfterCharge($event) { $this->raiseEvent('onAfterCharge', $event); }
}
| 類型 | 用途 | 生命週期 | 存取方式 |
|---|---|---|---|
| 元件 | 跨應用共享服務(DB、快取、API 客戶端) | 應用啟動至結束 | Yii::app()->componentId |
| 模組 | 獨立功能區塊(後台、API、商城) | 請求期間按需載入 | URL 路由進入 |
| 擴展 | 第三方套件(Composer 套件、Yii 擴展) | 視類型而定 | Composer autoload / 元件註冊 |
EmailComponent、StorageComponent)IComponent 介面,便於測試替換params.php 或環境變數,不寫死在元件preload,降低啟動開銷善用元件架構,能建立高內聚、低耦合、可測試的 Yii 應用基礎設施。