Yii項目開發總結

學習Yii好久了,一直作的是小案例,自覺得學的還不錯。直到最近用Yii開發了一個很是簡單的CMS,一路下來,磕磕絆絆,才知本身不足。加上最近正學習着偏架構方面的知識。特此總結一下。小白經驗,大神輕拍,歡迎討論。php

本篇文章主要是將一些 MVC 代碼組織的技巧,不會涉及詳細編碼。聲明使用的模版是Yii高級模板。java

痛苦的開發。

全部的php框架幾乎都遵循MVC模式設計,網絡各類教程、官方手冊,也是一股腦的說着按着MVC組織代碼。
先說說開發中個人悲慘歷史。數據庫

你們都知道,在Yii中,一張表對應一個AR,再對應一個控制器。c#

在開發開始的時候確實是不錯的。好比留言功能裏面。我在common\models下生成了對應的AR類。而後在frontendbackend的控制器裏導入了這個AR類,修改相應視圖。而後根據須要對查詢作了簡單封裝,便是在生成的AR類中寫了一些方法,而後控制器調用。功能實現,代碼邏輯也清晰。自覺棒棒噠。後端

而後就到痛苦的時候了。在設計文章和欄目的時候,我分了三張表:文章表,欄目表,文章內容表。在common\models生成三個AR類,後臺、前臺分別調用。因爲建立文章時三張表都須要同時用到,以及插入、修改、刪除的時候,須要用事務保證一致性。因而我只能就在文章的控制器裏添加了一個又一個涉及數據庫操做的方法。而後在前臺顯示的時候,又在對應的模型類裏添加了一些方法,前臺控制器又是通常修改。首頁顯示的控制器,映入了八個AR類。而後到最後,看着控制器裏一個個AR查詢的方法,AR類中又是一堆不一樣的查詢方法,我完全懵逼了。php框架

好不容易實現完功能,本身都不敢看本身的代碼了。微信

MVC中M的思考

開發完以後,痛定思痛。在大量閱讀博客、書籍之下。得到如下經驗,與君共享。網絡

關於MVC中,首先聲明的一點是設計要「胖Model痩Controller」,即Controller應該只有薄薄的一層。主要業務邏輯都在Model中。架構

視圖層和控制層不用多談,你們都知道。主要該談談的是模型層。app

模型中先後臺的組織

對於先後都要用到的模型,你們都會生成AR類到common\models,而後在frontendbackend的控制器裏導入了這些AR類。可是,這不是一個好的習慣。先後臺有着不一樣的應用邏輯。引用同一個AR類必然職責不清。正確的作法是在先後臺的models文件夾裏,新建不一樣的類,而後繼承common\models中的AR類,作到模型分離。

舉個例子。在common\models中有個Post.phpAR類,你應該在backend\models中新建一個Post.php而後繼承common\models中的Post.php類。前臺也是如此,作到引用分離。

業務邏輯層(service)

開發中一定涉及到多表關聯。若是所有在控制器中引入模型類,寫查詢語句,代碼組織就會很是糟糕,不利於維護管理,更正確的作法是。創建一個業務邏輯層(service)。

也就是作backendfrontend文件夾下創建一個services文件夾,保存咱們的業務邏輯。好比我前面有三張表:文章表,欄目表,文章內容表,分別對應三個模型。當我須要保存一片文章時,同時涉及到三張表的操做。我就能夠創建一個PostService.php,裏面引入這三個AR類,而後創建一個SavePost()方法,在方法裏同時對三張表作操做。這樣,控制器裏只需引入這個服務類,調用相應方法就好了。

讀寫分離。

實際的應用都是讀多寫少,所以,咱們能夠作到代碼層面的讀寫分離。(詳細的能夠了解了解CQRS架構),方便分別優化。並且Yii中的AR雖然很方便,可是效率不高,太複雜的查詢也是很差實現的。

這裏Yii提供了一個簡單高效的SQL查詢。那就是DAO
就是使用方式是這個的東西。

$post = Yii::$app->db->createCommand('SELECT * FROM post WHERE id=:id AND status=:status') ->bindValue(':id', $_GET['id']) ->bindValue(':status', 1) ->queryOne(); 

咱們能夠在services文件夾裏創建只提供查詢的文件,好比PostQuery.php文件提供對文章的查詢

總結

第一次開發一個完整的東西,學習到了不少。最近打算對這個CMS進行重構。道路阻且長,加油!

 layouts 佈局 數據

  • Lan_allofme
    Lan_allofme 評論於 2016-12-01 15:11  舉報

    樓主寫的不錯,但願分享更多經驗

  • 玩個錘子
    玩個錘子 評論於 2016-12-02 01:05  舉報

    寫的不錯!我也是剛剛學習,交流下經驗。對於model層,我通常都是放在common中,可是爲了防止混淆,我會創建表單模型,譬如:Post.php,我會讓它對應一個PostForm.php(繼承自Model),讓它處理業務邏輯,Post.php僅僅處理簡單的數據操做或者徹底就是一個數據模型。若是,按照樓主的方法,雖然先後端代碼分離的更加清晰,可是我想這樣作代碼是否是會有不少重複了。。畢竟,模型層的操做會有不少同樣的。

    共 1 條回覆
    石頭楊
    石頭楊 評論於 2016-12-02 10:07  回覆

    嗯嗯,學習了,這個方法不錯。關於先後端分別建一個 Model,繼承 common 中的 model,也只是針對一些複雜的,須要較多業務操做的,簡單的直接 common 中一個model 就好了。一切根據需求來就好了,不致使過分設計。

  • bubifengyun
    bubifengyun 評論於 2016-12-02 13:26  舉報

    至關不錯。個人也是都放在 common/models 只有特殊的才放在 各自 frontend 或 backend 文件夾下。都沒有考慮過繼承。

  • bingcool
    bingcool 評論於 2016-12-05 10:09  舉報

    總結的不錯,學習了

  • 藍天白雲11846
    藍天白雲11846 評論於 2016-12-06 16:44  舉報

    至關不錯;特別是對於模型處理;還有就是處理業務邏輯service與java的思想差很少

  • huangboyii
    huangboyii 評論於 2016-12-12 14:17  舉報

    AR模型雖然效率低一些,可是有更多的高級功能。好比事件,行爲,事務等等。拿寫操做來講,AR模型中提供beforeSave, afterSave這這兩個方法,這兩個方法會觸發相應的事件,你能夠在這些事件上綁定一些事件處理器完成對寫流程的控制或者完成額外的一些操做,這是Yii2操做數據庫最爲高級的方式,也是最精華的優勢之一。我的覺得,犧牲點運行性能,增長開發和理解上的便利性是划算的。

    共 2 條回覆
    石頭楊
    石頭楊 評論於 2016-12-12 16:38  回覆

    很差意思,是我沒有表述清楚。我說的是代碼層面的讀寫分離。並非全用 SQL 語句。

    數據庫操做就涉及增、刪、改、查,其中增、刪、改都是會對數據庫的內容的狀態形成改變,而查操做是不會對數據產生修改的。

    針對這個特性,咱們能夠在代碼層面作出讀(即查)寫(即增、刪、改)分離。便於針對不一樣的優化。

    我提出的是,寫操做使用 AR 模型,讀操做則直接用 SQL 語句。

    緣由有這麼幾點:

    • 通常的應用中80%是讀,20%是寫,或者更高。AR 效率低,用來作讀性能消耗太大。
    • 使用 AR 作讀的話,所有采用面向對象的方式,一些複雜的查詢不宜實現。
    • 其次使用 AR 作讀,你並不瞭解最終生成的 SQL 是什麼樣的。檢測到一些SQL語句執行過慢時,AR 中很差優化。

    其實究根結底,最終仍是爲了性能和維護。

    huangboyii
    huangboyii 評論於 2016-12-20 09:26  回覆

    我認爲你的觀點——使用AR模型作寫操做,而用SQL作讀操做很是有道理。Yii的讀操做也是分爲幾個層次,原生態上SQL,DAO和AR模型。DAO的方式讀,也提供了Query和BuildQuery幫你生成複雜的SQL語句,可是執行的方式幾乎仍是和PDO同樣,因此效率高的同時,方便性也獲得保障。

相關文章
相關標籤/搜索