Yii 學習筆記

關於寫代碼的順序

在學習使用表單的章節中,作者先寫Model的代碼,然後寫controller的代碼,最後寫View的代碼。這不是一個偶然,在使用thinkPHP框架寫代碼的時候,也同樣遇到過類似的問題,開始寫代碼的時候不知道從那裏入手比較順。實際上,如果模型沒有定義好,證明整個業務邏輯沒有理清,沒有理清業務當然就構建不出模型來,所以教程裏面的順序安排也給了自己指導意見,將來的代碼邏輯裏面應該從模型開始,快速搭建代碼框架,跑通業務流程,然後細化細節。

Yii框架處請求的邏輯

這裏寫圖片描述

小知識點

1、yii\base\Model 被用於普通模型類的父類並與數據表無關。yii\db\ActiveRecord 通常是普通模型類的父類但與數據表有關聯

2、表達式 Yii::$app 代表應用實例,它是一個全局可訪問的單例。同時它也是一個服務定位器,能提供 request,response,db 等等特定功能的組件。

3、當一個操作中調用了 yii\web\Controller::render() 方法時,它將會按 views/控制器 ID/視圖名.php 路徑加載 PHP 文件。主要的兩個目錄是:controllers和views,對應關係是一個controller對應views的一個目錄,對應規則是”控制器 ID“。
Yii中處理控制器ID和操作 ID是一樣的規則, 總是被以小寫處理,如果一個ID 由多個單詞組成,單詞之間將由連字符連接(如 create-comment)。ID 映射爲控制器名或者方法名時移除了連字符,將每個單詞首字母大寫,並加上 action 前綴。 例子:操作 ID create-comment 相當於方法名 actionCreateComment。

關鍵知識點

  • 屬性(Property)
    個人偏向於把“屬性”直接等同於面對相對編程的“成員變量”,yii裏把面向對象的成員變量以術語Property來表示。
    PHP是弱類型語言,可以隨時給對象新增成員變量,Yii裏通過客戶化的__set()和__get()限制了這個能力(yii\base\Object),從而確保了成員變量的安全性、封裝性。嚴格來處理應該儘量不寫public的成員變量,都寫private,且都要使用get和set方法來獲取私有變量的,可是PHP的魔術方法__set()和__get()又可以讓我們具有向訪問公有成員變量一樣訪問私有成員變量。因此總括起來,我個人理解,yii裏屬性的概念就是成員變量,並沒有差異。
    當然,安全性和封裝性所帶來的好處還是很多的。 一般而言,成員變量對外不可見是比較好的編程習慣。特別是突然某一天業務需求變更某個成員變量展示的長度、或者格式、或者其他客戶化變更的時候,這個編程習慣會帶來很暢快的體驗。

  • yii\base\Object / yii\base\Component
    Yii裏面提供了Object和Component兩個頂層基類,Component由於增加了event和behavior這兩個特性, 在方便開發的同時,也犧牲了一定的效率。 如果開發中不需要使用event和behavior這兩個特性,比如表示一些數據的類。 那麼,可以不從Component繼承,而從Object繼承。

  • 事件(Event)yii\base\Event
    事件既是代碼解耦的一種方式,也是設計業務流程的一種模式。
    如果沒有事件這個功能,類似功能怎麼做?
    如果沒有事件的處理機制,每次遇到某個特定場景或者特定值的時候,就需要執行某段固定的代碼,這段代碼如果只被一個地方使用,那沒有事件機制也沒什麼不妥,如果這個代碼被很多地方使用,就需要把代碼抽取出來成爲獨立的函數,方便被多個地方調用。如果只調用這個函數自己就也還好,如果調用多個函數,就得寫多行調用代碼,行數足夠多之後很自然就會想辦法把函數都封裝都一個統一的函數裏面進行管理。這樣的代碼邏輯再往上抽象和優化組織就會成爲事件這種機制。
    適合使用事件的場景,做一件事觸發接下來好多個處理步驟的場景。而組件提供的事件處理程序其實僅僅是同步的,不是異步的,就是handler一定要即時返回處理結果。
    事件的綁定可以在運行時以代碼的形式進行綁定,也可以在配置中進行綁定,這個配置生效的過程其實也是在運行時的。

  • 行爲(Behavior)yii\base\Behavior
    使用行爲(behavior)可以在不修改現有類的情況下,對類的功能進行擴充。
    關於屬性的注入是通過set和get函數實現的,而函數的注入是通過__call()函數實現的。
    要理解行爲與繼承和特性(Traits) 的區別。行爲更多是在給原有類定義添加功能的時候使用的,而這些要被添加的功能又要被其他類進行共享,如果沒有其他類進行共享,就沒有必要做這樣的事情。另外,這些功能還跟原類沒有明顯的繼承關係。而Yii中的行爲更多是爲了擴展事件的處理能力而設計的,並不僅僅是爲了增加類的特性。

  • MVC模式
    Model是指數據模型,是對客觀事物的抽象。
    View是指視圖,也就是呈現給用戶的一個界面,是model的具體表現形式,也是收集用戶輸入的地方。
    Contorller指的是控制器,主要負責與model和view打交道。

    web網站的開發工作很大部分是集中在model層,model層的代碼量會非常多,必然的選擇就是對model進行分層、分模塊,在Yii框架的gii工具的幫助下,其實針對model會產生三個類:model、modelQuery、modelSearch , 我個人的理解就是,model基本是跟數據庫表一一對應的(但是也不排出有擴展),query是寫業務邏輯的地方,search是編寫查詢條件的類,針對不同業務邏輯需要不同的查詢邏輯。

  • 依賴注入
    使用第三方資源時,都需要優先考慮依賴注入的設計模式,因爲基本上是會出現多種類型資源供選擇的情況。譬如:發送郵件、短信;撥打電話;支付;連接數據庫等等。在代碼邏輯過程中,需要使用很多第三方資源的話,就可以考慮依賴注入的設計思路。
    1、首先要考慮 依賴倒置原則(Dependence Inversion Principle, DIP),上層定義接口,下層實現接口,其實下層更多的是針對第三方資源提供的操作函數進行二次封裝,以便對本系統提供公共操作的入口,這樣每追加資源的時候就會有很熟悉的代碼流程。這是基本原則,是實現依賴注入的設計模式的基礎。

2、依賴倒置是一種編程思想,在這種思想的指導下,新加資源只需要編寫一個對應的接口類即可。但是實例化接口類的代碼還是得寫,這樣也會改動原來的代碼,這個改動不管多少,都會多多少少引入BUG。IoC,控制反轉(Inversion of Control, IoC),核心思想是將類(上層)所依賴的單元(下層)的實例化過程交由第三方來實現。這個具有實例化對象能力的第三方有點像工廠方法,但是不能說是工廠方法,工廠方法更多是用於創建同類資源,而這個第三方是要用於創建所有對象的,是一個更高層的抽象,在Yii框架中這個第三方叫做”控制反轉容器“,提供了動態地創建、注入依賴單元,映射依賴關係等功能。

Controller的重點內容

1、每個控制器都有一個由 yii\base\Controller::defaultAction 屬性指定的默認操作。默認是index。
2、controller裏面有內聯操作 和 獨立操作 的概念,但是在項目裏,更好的做法是通過繼承來共享操作。

Model的重點內容

1、model存儲數據的時候是沒有過濾特殊標籤的,展示數據的時候要處理好跨域攻擊的隱患。
2、控制場景的使用個數,通過繼承的方式獨立各個場景比用scenarios好。
3、塊賦值只處理安全屬性,非安全屬性需要手工處理。

View的重點內容

1、 將預定義變量列到視圖文件頭部註釋處,這樣可被IDE編輯器識別。
2、當創建生成HTML頁面的視圖時,在顯示之前將用戶輸入數據進行轉碼和過濾非常重要。純文本可調用 yii\helpers\Html::encode() 進行轉碼,HTML內容可調用 yii\helpers\HtmlPurifier()
3、存儲渲染後的頁面到數據庫或者靜態頁面可以用:
echo \Yii::app>view>renderFile(@app/views/site/license.php);4yii\base\Viewyii\base\View::params5 this 和 contentyii\base\View調yii\base\Controller::render()6 this 和 $content,前者對應和普通視圖類似的yii\base\View 視圖組件 後者包含調用yii\base\Controller::render()方法渲染內容視圖的結果。

Modules

關於modules,個人覺得有可能的話儘量避免使用。因爲既然考慮到Modules了,爲啥不考慮分獨立系統呢?分獨立系統會讓整個項目更簡潔,更獨立。也降低開發人員破壞代碼的風險。
不過,如果是採用過度方案就可以考慮下使用。就是在獨立子系統之前使用modules做代碼隔離,方便將來獨立成子系統,不過有時候這是一個謊言,隔離之後還有沒有動力獨立成子系統,是一個比較有意思的問題。

Filters(非常重要)

過濾器是 控制器 動作 執行之前或之後執行的對象,記住是控制器執行前或後。 例如訪問控制過濾器可在動作執行之前來控制特殊終端用戶是否有權限執行動作, 內容壓縮過濾器可在動作執行之後發給終端用戶之前壓縮響應內容。
過濾器本質上是一類特殊的 行爲,所以使用過濾器和 使用 行爲一樣。
核心過濾器:
- yii\filters\AccessControl:決定允許還是拒絕請求動作的執行, 如果沒有規則符合,訪問就會被拒絕。
- 認證方法過濾器:通常在實現RESTful API中使用。
- yii\filters\ContentNegotiator:ContentNegotiator支持響應內容格式處理和語言處理。 通過檢查 GET 參數和 Accept HTTP頭部來決定響應內容格式和語言。
- yii\filters\HttpCache:HttpCache利用Last-Modified 和 Etag HTTP頭實現客戶端緩存。
- yii\filters\PageCache:PageCache實現服務器端整個頁面的緩存。
- yii\filters\RateLimiter:RateLimiter 根據 漏桶算法 來實現速率限制。
- yii\filters\VerbFilter:VerbFilter檢查請求動作的HTTP請求方式是否允許執行, 如果不允許,會拋出HTTP 405異常。
- yii\filters\Cors:跨域資源共享 CORS 機制允許資源可以通過其他域名訪問獲取。

widget

小部件是Yii框架中一套管理前端組件的方案,是一套複用前端代碼的好方法。只可惜在多數項目裏面都沒有被很好地使用,如果我來做開發規範的話,我覺得我會把這種程度的複用使用到極致的。
- yii\jui\DatePicker:日期選擇器小部件
- yii\widgets\ActiveForm:
- yii\widgets\Menu:
- yii\widgets\LinkPager:
小部件設計時應是獨立的,也就是說使用一個小部件時候, 可以直接丟棄它而不需要額外的處理。 但是當小部件需要外部資源如CSS, JavaScript, 圖片等會比較棘手, 幸運的時候Yii提供 資源包 來解決這個問題。

Assets前端資源

當在視圖中註冊一個資源包, 在渲染Web頁面時會包含包中的CSS和JavaScript文件。
定義資源包:資源包指定爲繼承yii\web\AssetBundle的PHP類。
Cache Busting:通過參數來讓瀏覽器刷新緩存文件。
合併和壓縮資源:一個Web頁面可以包含很多CSS 和/或 JavaScript 文件,爲減少HTTP 請求和這些下載文件的大小, 通常的方式是在頁面中合併並壓縮多個CSS/JavaScript 文件爲一個或很少的幾個文件, 並使用壓縮後的文件而不是原始文件。

如果後臺工作人足夠或者前端工作人員有能力,都可以考慮使用yii來做資源管理,看起來功能還是很全很強大的,但是對前端開發有一定的要求。

擴展(Extensions)

快速獲取SDK或者自己開發SDK。
有些優秀的擴展可以直接使用,閱讀過其中一兩個的源碼之後,熟悉擴展的開發規範和方法之後,遇到一些需求可以先搜搜是否有好用的擴展直接使用。在packlist裏面搜。

路由

當入口腳本在調用 yii\web\Application::run() 方法時,它進行的第一個操作就是解析輸入的請求,然後實例化對應的控制器操作處理這個請求。 該過程就被稱爲引導路由(routing)。
普通的格式優化
Rest支持
創建URL
URL後綴

錯誤處理

  • 使用錯誤處理器:yii\web\ErrorHandler 註冊成一個名稱爲errorHandler應用組件即可完成全局的錯誤處理機制。
  • 使用錯誤操作 :yii\web\ErrorHandler::errorAction 屬性錯誤路由到一個操作, 上述配置表示不用顯示函數調用棧信息的錯誤會通過執行site/error操作來顯示。
  • 自定義錯誤格式 :在做API接口的時候就比較有用了。

日誌

  • Yii::trace():記錄一條消息去跟蹤一段代碼是怎樣運行的。這主要在開發的時候使用。
  • Yii::info():記錄一條消息來傳達一些有用的信息。
  • Yii::warning():記錄一個警告消息用來指示一些已經發生的意外。
  • Yii::error():記錄一個致命的錯誤,這個錯誤應該儘快被檢查。

  • 日誌目標:
    一個日誌目標是一個 yii\log\Target 類或者它的子類的實例。 它將通過他們的嚴重層級和類別來過濾日誌消息,然後將它們導出到一些媒介中。

  • 性能分析:
    性能分析是一個特殊的消息記錄類型,它通常用在測量某段代碼塊的時間, 並且找出性能瓶頸是什麼。

組件(Component)

Yii的組件是 yii\base\Component 類或其子類的實例,主要提供了三項功能:
- 屬性(Property):要注意於類成員變量做區分。
- 事件(Event):事件可以將自定義代碼“注入”到現有代碼中的特定執行點。這種機制可以很好得控制代碼粒度,提高代碼的複用能力。
- 行爲(Behavior):可以無須改變類繼承關係即可增強一個已有的yii\base\Component 類功能。更多的情況下是結合事件來組織代碼。

配置

在 Yii 中,創建新對象和初始化已存在對象時廣泛使用配置。配置通常包含被創建對象的類名和一組將要賦值給對象屬性的初始值。還可能包含一組將被附加到對象事件上的句柄。和一組將被附加到對象上的行爲。
Yii::createObject() 方法接受一個配置數組並根據數組中指定的類名創建對象。對象實例化後,剩餘的參數被用來初始化對象的屬性,事件處理和行爲。

別名(Aliases)

通過 Yii::setAlias() 定義的別名稱爲根別名,而用他們衍生出去的別名成爲衍生別名。

類自動加載(Autoloading)

要使用 Yii 的類自動加載器,你需要在創建和命名類的時候遵循兩個簡單的規則:
- 每個類都必須置於命名空間之下 (比如 foo\bar\MyClass)。
- 每個類都必須保存爲單獨文件,且其完整路徑能用以下算法取得:

// $className 是一個開頭包含反斜槓的完整類名
$classFile = Yii::getAlias('@' . str_replace('\\', '/', $className) . '.php');

Yii 類自動加載器支持類映射表功能,該功能會建立一個從類的名字到類文件路徑的映射。優先級更高。

服務定位器

服務定位器是一個瞭解如何提供各種應用所需的服務(或組件)的對象。 在服務定位器中,每個組件都只有一個單獨的實例,並通過ID 唯一地標識。 用這個 ID 就能從服務定位器中得到這個組件。
最常用的服務定位器是application(應用)對象,可以通過 \Yii::$app 訪問。

依賴注入容器

Yii 通過 yii\di\Container 類提供 DI 容器特性。它支持如下幾種類型的依賴注入:
- 構造方法注入;
- Setter 和屬性注入;
- PHP 回調注入.

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