概述
同laravel一樣,yii應用也有兩個入口,分別是
web
基礎應用 和console
控制檯應用
-
入口指令碼
- 定義全域性常量
- 註冊
Composer
自動載入器 - 包含
Yii
類檔案 - 載入應用配置
- 建立一個應用例項並配置
- 呼叫
yii\base\Application::run($config)
來處理請求
-
應用主體
- 例項化
(new yii\web\Application($config))->run()
- 屬性
- 必要屬性
id, basePath
- 重要屬性
aliases
,bootstrap
- 可將模組ID加入到
bootstrap
陣列中 - bootsrap 屬性中每個元件需要指定以下一項
- 應用 元件 ID
- 模組 ID
- 類名
- 配置陣列
- 建立並返回一個元件的無名稱函式
catchAll
屬性 僅Web applications
網頁應用支援- 指定一個要處理所有使用者請求的 控制器方法, 通常在維護模式下使用,同一個方法處理所有使用者請求
如果模組 ID 和應用元件 ID 同名,優先使用應用元件 ID 在啟動階段,每個元件都會例項化。如果元件類實現介面
yii\base\BootstrapInterface
,也會呼叫 bootstrap() 方法
- 指定一個要處理所有使用者請求的 控制器方法, 通常在維護模式下使用,同一個方法處理所有使用者請求
- 可將模組ID加入到
- 必要屬性
- 例項化
-
應用元件
components
配置- 每一個應用元件指定一個key-value對的陣列,key代表元件ID, value代表元件類名或 配置
- 應用中註冊的元件,可以通過表示式 \Yii::$app->ComponentID 全域性訪問
-
屬性
controllerMap
- 指定一個控制器 ID 到任意控制器類
- 陣列的鍵代表控制器ID, 陣列的值代表對應的類名
-
屬性
controllerNamespace
- 該屬性指定控制器類預設的名稱空間,預設為
app\controllers
- 該屬性指定控制器類預設的名稱空間,預設為
-
屬性
modules
,鍵為模組id -
language
,name
,全域性可訪問的引數params
-
sourceLanguage, timeZone
語言,時區 -
實用屬性
charset
應用使用的字符集defaultRoute
該屬性指定未配置的請求的響應 路由 規則,可能包含模組 ID,控制器 ID,動作 IDextensions
該屬性用陣列列表指定應用安裝和使用的 擴充套件, 預設使用@vendor/yiisoft/extensions.php
檔案返回的陣列layout,layoutPath,runtimePath,viewPath,vendorPath,enableCoreCommands
應用事件
- 應用在處理請求過程中會觸發的事件
on eventName
語法配置事件處理程式碼
- 事件
EVENT_BEFORE_REQUEST
EVENT_AFTER_REQUEST
EVENT_BEFORE_ACTION
EVENT_AFTER_ACTION
- 流程
- 應用主體物件觸發
beforeAction
事件 --> 模組觸發 --> 控制器觸發 - 注意 模組 和 控制器 都會觸發 afterAction 事件。 這些物件的觸發順序和
beforeAction
相反
- 應用主體物件觸發
任何一個事件處理中設定 yii\base\ActionEvent::$isValid 設定為 false 會停止觸發後面的事件
應用元件
- 應用主體是服務定位器, 它部署一組提供各種不同功能的 應用元件 來處理請求
- 訪問已註冊到應用上的元件例項
\Yii::$app->componentID
- 應用元件在 應用主體配置
yii\base\Application::$components
屬性
應用元件就像全域性變數,謹慎註冊太多應用元件 一個應用元件只會在第一次訪問時例項化, 如果處理請求過程沒有訪問的話就不例項化
- 可以使用閉包來引導啟動自定義的元件
- 核心應用元件(類似laravel中的應用啟動陣列)
request
元件 用來收集使用者請求並解析 路由db
代表一個可以執行資料庫操作的資料庫連線assetManager
管理資源包和資源釋出errorHandler:
處理 PHP 錯誤和異常formatter:
格式化輸出顯示給終端使用者的資料i18n
: 支援資訊翻譯和格式化log
: 管理日誌物件yii\swiftmailer\Mailer
支援生成郵件結構併傳送response
: 代表傳送給使用者的響應session
: 代表會話資訊urlManager
: 支援URL地址解析和建立user
: 代表認證登入使用者資訊,僅在Web applications
網頁應用中可用view
: 支援渲染檢視
控制器
- 繼承
yii\base\Controller
類的物件,負責處理請求和生成響應 - 動作
- 控制器由 操作 組成,它是執行終端使用者請求的最基礎的單元, 一個控制器可有一個或多個操作
- 路由
- 終端使用者通過所謂的路由尋找到動作
- 模組ID: 僅存在於控制器屬於非應用的模組
- 控制器ID: 同應用(或同模組如果為模組下的控制)
- 操作ID: 同控制器下唯一標識操作的字串
- 建立
- 控制器應繼承
yii\web\Controller
或它的子類 - 繼承
yii\console\Controller
或它的子類 - 控制器ID 應僅包含英文小寫字母、數字、下劃線、中橫槓和正斜槓
- 控制器應繼承
- 控制器佈署
- 通過配置
controller map
來強制上述的控制器ID和類名對應, - 應用場景 在使用第三方不能掌控類名的控制器上
- 通過配置
- 建立動作
- 內聯操作 無需重用的情況下優先使用
- 獨立操作
繼承 yii\base\Action
或它的子類的類- 主要用於多個控制器重用,或重構為擴充套件
- 應用場景如
yii\web\ViewAction
,yii\web\ErrorAction
要使用獨立操作,需要通過控制器中覆蓋
yii\base\Controller::actions()
方法在action map中申明 建立的獨立操作類,必須實現公有的名稱為run()
的方法,與操作方法類似
- 動作結果
- 返回值可為 響應 物件,作為響應傳送給終端使用者
- 對於
Web applications
網頁應用,返回值可為任意資料, 它賦值給yii\web\Response::$data
- 對於
console applications
控制檯應用,返回值可為整數, 表示命令列下執行的exit status
退出狀態
- 動作引數,對於Web
applications
網頁應用, 每個動作引數的值從$_GET中獲得,引數名作為鍵 - 預設動作
- 當路由 只包含控制器ID, 會使用所請求的控制器的預設操作
- 由控制器中的
$defaultAction
指定預設動作
- 控制器生命週期
- 應用主體 --> 請求路由 --> 建立控制器
- 控制器
init()
方法被呼叫 - 建立操作物件
- 未提供ID,使用
default action ID
預設操作ID - 在
action map
(控制器actions方法) 找到操作ID, 會建立一個獨立操作 - 操作ID對應操作方法,會建立一個內聯操作
- 否則會丟擲
yii\base\InvalidRouteException
異常
- 未提供ID,使用
- 控制器按順序呼叫應用主體、模組(如果控制器屬於模組)、 控制器的 beforeAction() 方法
- 任意一個呼叫返回false,後面未呼叫的
beforeAction()
會跳過並且操作執行會被取消 - 預設情況下每個
beforeAction()
方法會觸發一個 beforeAction 事件
- 任意一個呼叫返回false,後面未呼叫的
- 控制器執行操作
- 控制器按順序呼叫控制器、模組(如果控制器屬於模組)、應用主體的 afterAction() 方法
- 應用主體獲取操作結果並賦值給響應
- 控制器
- 應用主體 --> 請求路由 --> 建立控制器
- 小結
- 訪問請求資料
- 根據請求資料呼叫模型方法和其他服務元件
- 使用檢視構造響應
- 不應處理被模型處理的請求資料
- 應避免嵌入html或其他程式碼,這些程式碼最好在檢視中處理
模型類
- 代表業務資料,規則和邏輯的物件
yii\base\Model
類特性- 屬性
- 定義 覆蓋
attriutes()
指定模型所擁有的屬性 或定義非靜態公有成員變數 - 實現了
ArrayAccess
陣列訪問,ArrayIterator
陣列迭代器
- 定義 覆蓋
- 屬性標籤
$model->getAttributeLabel('name')
- 通過使用模型的 scenario場景, 可對相同的屬性返回不同的標籤
- 塊賦值
- 驗證規則
- 資料匯出
- 屬性
- 場景
- 在不同的場景下, 模型可能會使用不同的業務規則和邏輯
- 例如
email
屬性在註冊時強制要求有,但在登陸時不需要 - 使用
yii\base\Model::$scenario
屬性保持使用場景的跟蹤 - 可以通過覆蓋
yii\base\Model::scenarios()
方法來自定義行為 - 場景特性主要在驗證 和 屬性塊賦值 中使用
- 驗證規則
- 呼叫
yii\base\Model::validate()
來驗證接收到的資料 - 使用
yii\base\Model::rules()
申明的驗證規則 - 使用
yii\base\Model::$errors
屬性儲存錯誤
- 呼叫
- 非安全屬性驗證
- 在
scenarios()
方法中屬性名加一個驚歎號!
- 應用場景 在某些情況下,可能想驗證一個屬性但不想讓他是安全
- 在
- 資料匯出
- 模型轉換成陣列
yii\base\Model::attributes()
- 陣列轉換成需要的格式
- 通常使用 資料轉換器如
yii\web\JsonResponseFormatter
- 更靈活和強大的將模型轉換為陣列的方式是使用
yii\base\Model::toArray()
方法
- 通常使用 資料轉換器如
- 模型轉換成陣列
- 欄位
- 可以通過覆蓋
fields()
和/或extraFields()
方法來改變這種行為 fields()
方法定義的欄位是預設欄位, 表示toArray()
方法預設會返回這些欄位- 應用場景 通常使用覆蓋
fields()
方法過濾掉 一些包含敏感資訊的欄位
- 可以通過覆蓋
- 實踐
- 模型是代表業務資料、規則和邏輯的中心地方,通常在很多地方重用
- 不應直接訪問請求,session和其他環境資料, 這些資料應該由控制器傳入到模型
- 單個模型中避免太多的 場景
- 常用策略 定義可被多個 應用主體 或 模組 共享的模型基類集合。 這些模型類應包含通用的最小規則集合和邏輯
- 通過繼承對應的模型基類來定義具體的模型類,具體模型類包含應用主體或模組指定的規則和邏輯
檢視
- 檢視模板為PHP指令碼檔案, 主要包含HTML程式碼和展示類PHP程式碼,通過view應用元件來管理渲染檢視
- 組織檢視
- 控制器渲染的檢視檔案預設放在
@app/views/ControllerID
目錄下 - 對於 小部件 渲染的檢視檔案預設放在
WidgetPath/views
目錄 - 可覆蓋控制器或小部件的
yii\base\ViewContextInterface::getViewPath()
方法來自定義檢視檔案預設目錄
- 控制器渲染的檢視檔案預設放在
- 控制器中渲染
render()
: 渲染一個 檢視名 並使用一個 佈局 返回到渲染結果renderPartial()
: 渲染一個 檢視名 並且不使用佈局renderAjax()
: 渲染一個 檢視名 並且不使用佈局renderFile()
: 渲染一個檢視檔案目錄或 別名下的檢視檔案
- 小部件中渲染
render()
: 渲染一個 檢視名.renderFile()
: 渲染一個檢視檔案目錄或 別名下的檢視檔案
- 檢視中渲染
- 呼叫view component檢視元件提供的以下方法
render()
: 渲染一個 檢視名renderAjax()
: 渲染一個 檢視名 並注入所有註冊的JS/CSS指令碼和檔案
- 其他地方渲染
Yii::$app->view
訪問 view 應用元件
- 檢視名規則
- 可省略副檔名
- 以雙斜槓 // 開頭,對應的檢視檔案路徑為
@app/views/ViewName
- 檢視名以單斜槓/開始,檢視檔案路徑以當前使用模組 的
view path
開始
- 檢視中訪問資料
- 推送方式 是通過檢視渲染方法的第二個引數傳遞資料,據格式應為名稱-值的陣列
- 拉取方式 可讓檢視從
view component
檢視元件或其他物件中主動獲得資料(如Yii::app),app),‘this->context->id
view component
檢視元件提供params
引數屬性來讓不同檢視共享資料- 佈局中訪問資料,可使用兩個預定義變數
$this
和$content
- 前者對應和普通檢視類似的view 檢視元件 後者包含呼叫render()方法渲染內容檢視的結果
- 檢視事件
模組化
- 建立模組
- 存在一個模組類檔案,該檔案所在目錄稱之為
base_path
- 每個模組都有一個繼承 yii\base\Module 的模組類,該類可被自動載入
- 應用主體例項 類似會建立該模組類唯一例項,模組例項用來幫模組內程式碼共享資料和元件
- 通常模組塊類
init()
方法包含很多初始化模組屬性程式碼
- 存在一個模組類檔案,該檔案所在目錄稱之為
- 引導啟動模組
- 模組加入到應用主體的
bootstrap
屬性中 - 配置
modules
項,值為陣列,鍵為模組名,值模組類
- 模組加入到應用主體的
- 模組巢狀
- 子模組必須在父模組
modules
屬性中申明 - 模組在大型專案中常備使用,這些專案的特性可分組
- 子模組必須在父模組
過濾器
- 除了控制器外,可在 模組或應用主體 中申明過濾器
在模組或應用主體中申明過濾器,在only 和 except 屬性中使用路由 代替動作 ID, 因在模組或應用主體中只用動作ID並不能唯一指定到具體動作
-
過濾器是 控制器動作 執行之前或之後執行的物件
-
應用場景 許可權驗證,內容壓縮過濾器可在動作執行之後發給終端使用者之前壓縮響應內容
-
使用
- 過濾器 本質上是一類特殊的行為,可在控制器的
behaviors()
方法來宣告過濾器 - 控制器類的過濾器預設應用到該類的 所有 動作,
only
屬性則明確指定
- 過濾器 本質上是一類特殊的行為,可在控制器的
-
多個過濾器執行規則
- 預過濾
- 執行應用主體 --> 模組級別 --> 控制器 --> 若過濾器終止後續不再執行
- 成功通過預過濾器則進入執行動作
- 後過濾 倒序執行控制器過濾器--> 倒序模組中 --> 倒序執行應用主體中 behaviors() 列出的過濾器
- 預過濾
-
建立過濾器
- 若返回值為
false
則之後的過濾器和動作不會執行 - 繼承
yii\base\ActionFilter
類並覆蓋beforeAction()
或afterAction()
方法來建立動作的過濾器
- 若返回值為
-
核心過濾器(類似於java的概念,laravel中的是中介軟體)
- Yii 核心過濾器在
yii\filters
名稱空間下 AccessControl
提供基於rules
規則的訪問控制- 決定允許還是拒絕請求動作的執行,若無答合的規則,則訪問被拒絕
- 應用場景 比如使用者 IP 地址、登入狀態等等)的規則,
- 認證方法過濾器
- 認證方法過濾器類在
yii\filters\auth
名稱空間下 - 認證方法過濾器通過
HTTP Basic Auth
或OAuth 2
來認證一個使用者 - 如
yii\filters\auth\HttpBasicAuth
來認證一個使用者user identity class
類必須 實現findIdentityByAccessToken()
方法
ContentNegotiator
支援響應內容格式處理和語言處理- 通過
GET
引數和Accept HTTP
頭部來決定響應內容格式和語言 - 亦可在應用主體上配置。
- 如果請求中沒有檢測到內容格式和語言, 使用 formats 和 languages 第一個配置項
- 通過
- 認證方法過濾器類在
HttpCache
利用Last-Modified
和Etag HTTP
頭實現客戶端快取PageCache
實現伺服器端整個頁面的快取RateLimiter
根據 漏桶演算法 來實現速率限制,主要用在實現RESTful APIs
VerbFilter
檢查請求動作的 HTTP 請求方式是否允許執行, 如果不允許,會丟擲 HTTP 405異常Cors filter
應在授權/認證過濾器之前定義, 以保證CORS
頭部被髮送- 若要將CORS過濾器新增到 API 中的
yii\rest\ActiveController
類, 還要檢查REST Controllers
中的部分
- Yii 核心過濾器在
小部件Widgets
- 在檢視中使用的可重用單元, 使用物件導向方式建立複雜和可配置使用者介面單元
- Yii提供許多優秀的小部件
- 比如
active form,menu, jQuery UI widgets, Twitter Bootstrap widgets
- 比如
- 使用
- 在檢視中可呼叫
yii\base\Widget::widget()
方法使用小部件 - 小部件會在
begin()
和end()
執行處分別起止標籤
- 在檢視中可呼叫
呼叫
yii\base\Widget::end()
的時候,一些小部件將使用 輸出緩衝 來調整封閉的內容
- 小部件的全域性預設值可以通過 DI 容器配置, 如
\Yii::$container->set(xx,yy)
- 建立小部件
widget()
方法- 繼承
yii\base\Widget
類,覆蓋init()
或run()
方法 - 前者屬性賦值,後者返回小部件生成渲染結果的程式碼,通常大段程式碼採用
render
方法
- 繼承
begin()
和end()
方法- PHP 輸出緩衝
ob_start()
在init()
啟動 - 所有在
init()
和run()
方法之間的輸出內容都會被獲取,並在run()
處理和返回
- PHP 輸出緩衝
- 流程
begin
時會建立 一個新的小部件例項,並在構造結構時呼叫init 方法- 在
end
方法時,會呼叫run
方法並輸出結果
- 小結
- 通常邏輯程式碼在小部件類,展示內容在檢視中
- 小部件設計是獨立的,丟棄它不需要額外的處理
- 小部件是可以重用的類,檢視只是應用中使用的普通PHP指令碼
前端資源(Assets)
-
Yii 中的資源是和 Web 頁面相關的檔案,通常放在 web 可訪問的目錄下,直接被 Web 伺服器呼叫
-
在檢視中註冊一個資源包, 在渲染 Web 頁面時會包含包中的 CSS 和 JavaScript 檔案
-
定義資源包
- 資源包 放在一個目錄下的資源集合
- 資源包指定為繼承
yii\web\AssetBundle
的 PHP 類, 包名為可自動載入的 PHP 類名 - 在資源包類中,要指定資源所在位置,包含的檔案,以及其他包的依賴關係
-
資源位置
- 源資源,釋出資源,外部資源
- 推薦 指定
basePath
而不是sourcePath
-
資源依賴 通過
$depends
屬性來指定 -
資源選項
- 可指定 cssOptions 和 jsOptions 屬性來自定義頁面包含 CSS 和 JavaScript 檔案的方式,
- 這些屬性值會分別傳遞給
yii\web\View::registerCssFile()
和yii\web\View::registerJsFile()
方法 - 預設情況下,當釋出資源包時,所有在
yii\web\AssetBundle::$sourcePath
目錄裡的內容都會發布
-
使用資源包
- 在檢視中呼叫
yii\web\AssetBundle::register()
方法註冊資源 - 在檢視模板可使用如下程式碼註冊資源包
use app\assets\AppAsset;AppAsset::register($this);
- 在其他地方註冊資源包,應提供檢視對,如在小部件類中註冊資源包, 可以通過
$this->view
獲取檢視物件
- 在檢視中呼叫
-
動態資源包
- 應用場景 語言本地化覆蓋
yii\web\AssetBundle::init()
方法來實現 - 特定資源包 通過
yii\web\AssetBundle::register()
返回的例項進行調整
- 應用場景 語言本地化覆蓋
-
自定義資源包
assetManager
- Yii 通過配置名為
assetManager
的應用元件來使用yii\web\AssetManager
, 配置$bundles
屬性自定義資源包行為 - 在應用配置中配置
assetManager
設定cdn資源,sourcePath
則一定不要釋出該資源 - 資源包元件-->管理器-->bundles-->資源包類名-->對應的配置陣列
- 在
yii\web\AssetBundle::init()
方法內或在註冊的資源包物件上進行的調整優先於AssetManager
配置
- Yii 通過配置名為
-
資源對映 “修復”多個資源包中資原始檔的錯誤或者不相容
$assetMap
屬性 -
釋出資源
assetManager
- 可
basePath
和baseUrl
屬性自定義釋出位置 - 可使用符號連結(若系統允許)
'linkAssets' => true,
- 資源包放在 Web 不能訪問的目錄, 當檢視註冊資源時資源會被拷貝到一個 Web 可訪問的目錄中
- 可
-
清除快取
'appendTimestamp' => true
-
常用資源包
yii\web\YiiAsset
包含 yii.js 檔案yii\web\JqueryAsset
包含 jQuery Bower 包的 jquery.js 檔案yii\bootstrap\BootstrapAsset
包含 Twitter Bootstrap 框架的 CSS 檔案yii\bootstrap\BootstrapPluginAsset
JavaScript 檔案yii\jui\JuiAsset
包含 jQuery UI 庫的 CSS 和 JavaScript 檔案
-
資源轉換
yii\web\AssetManager::$converter
自定義預處理命令和支援的擴充套件語法yii\web\AssetConverter::$commands
屬性指定支援的擴充套件語法
-
合併和壓縮
asset manager
資源管理器asset
命令 自動處理資源包命令(生成相應配置檔案)yii asset/template assets.php
jsCompressor 和 cssCompressor
定控制檯命令或PHP回撥函式來處理合並和壓縮
- 資源包分組
- 指出輸出的bundles包分組,
allShared,allBackEnd,allFrontEnd
- 指出輸出的bundles包分組,
擴充套件
- 類的自舉引導
bootstrapping class
(自舉類)實現yii\base\BootstrapInterface
介面- 實現
bootstrap
方法,接收主體應用引數, 置於myname\mywidget
名稱空間之下 - 應用場景 擴充套件可響應應用的
beginRequest
事件,做一些環境的設定工作 - 將自舉類在 composer.json 檔案中列出來,每一個請求的自舉過程中,自動例項化自舉類並呼叫其 bootstrap() 方法
- 運算元據庫
- 在需要訪問資料庫的類中申明一個 db 屬性,該屬性擴充套件使用哪個DB連線
- 提供 資料遷移 來運算元據庫的結構修改,而不是使用SQL文字檔案
- 儘量使遷移檔案適用於不同的 DBMS
- 在遷移檔案中避免使用 Active Record
- 使用Assets
- 手動這些 asset 檔案拷貝到特定的 Web 可以讀取的資料夾
- 申明一個 asset bundle 並依靠 asset 釋出機制自動將這些檔案
- 國際化和本地化
- 擴充套件為終端使用者顯示資訊,這些資訊應該用 Yii::t() 包裝起來,以便可以進行翻譯
- 若擴充套件顯示數字、日期等,用 yii\i18n\Formatter 中適當的格式化規則做格式化