本文所說的Laravel 2018使用資料分析,指的是
Laravel Shift
的作者Jason McCreary
,基於使用Laravel Shift
的超過8000個laravel應用所做的分析。(Laravel Shift
是一個自動升級你的laravel版本的付費應用,比如你的專案版本是5.1,使用它呢可以自動給你升級到5.6,這期間省去你手動升級的繁瑣和煩惱。)
更好的閱讀體驗請移步:www.pilishen.com/posts/larav…
截至到2018年7月,Laravel Shift
裡有超過8500個上傳的laravel apps,每一次版本的升級,Laravel Shift
都會生成一個日誌檔案以用於debug,基於這些日誌檔案,產生了今天我們提到的laravel使用資料。下面是Laravel Shift
裡日誌檔案一瞥:
*** _Shift_ version: 0281cff03fee62f250253f1e485dc7a790209866
*** Cloning app...
>>> _Shift_ 5.2 Event: app did not contain references to SelfHandling
>>> _Shift_ 5.2 Event: could not upgrade middleware Data: ["app\/Http\/Middleware\/Authenticate.php","app\/Http\/Middleware\/EncryptCookies.php","app\/Http\/Middleware\/RedirectIfAuthenticated.php"]
>>> _Shift_ 5.2 Event: could not upgrade app/Providers/RouteServiceProvider.php
>>> _Shift_ 5.2 Event: could not patch app/Providers/RouteServiceProvider.php
>>> _Shift_ 5.2 Event: could not find User model path
>>> _Shift_ 5.2 Event: found additional uses of Event names
>>> _Shift_ 5.2 Event: matched core file: phpunit.xml with version: 5.1.11
>>> _Shift_ 5.2 Event: matched core file: tests/TestCase.php with version: 5.1.33
>>> _Shift_ 5.2 Event: matched core file: database/migrations/2014_10_12_100000_create_password_resets_table.php with version: 5.1.33
>>> _Shift_ 5.2 Event: matched core file: public/.htaccess with version: 5.1.33
>>> _Shift_ 5.2 Event: matched core file: config/broadcasting.php with version: 5.1.11
>>> _Shift_ 5.2 Event: matched core file: config/cache.php with version: 5.1.33
>>> _Shift_ 5.2 Event: matched core file: config/compile.php with version: 5.1.33
>>> _Shift_ 5.2 Event: matched core file: config/database.php with version: 5.1.11
>>> _Shift_ 5.2 Event: matched core file: config/filesystems.php with version: 5.1.33
>>> _Shift_ 5.2 Event: matched core file: config/queue.php with version: 5.1.11
>>> _Shift_ 5.2 Event: matched core file: config/view.php with version: 5.1.33
>>> _Shift_ 5.2 Event: could not upgrade config files Data: {"1":"config\/auth.php","2":"config\/mail.php","3":"config\/services.php","4":"config\/session.php"}
>>> _Shift_ 5.2 Event: could not upgrade package.json
>>> _Shift_ 5.2 Event: app contained phpspec/phpspec requirement of ~2.1
>>> _Shift_ 5.2 Event: found customized namespace
*** _Shift_ ran in: 212.209509
複製程式碼
從這些日至裡可以看到哪些檔案被升級了,用到了哪些功能、哪些元件,等等。
(一)最流行的Laravel版本——5.3
很多apps停留在了5.3,可能因為PHP版本的要求,因為到了5.4測試想轉換到Dusk,或者auth元件的變化等。
這應該符合現實情況,因為laravel在5.2~5.3期間一方面做了很多變動,大家要逐步適應和學習,另一方面這些人性化的變動也讓laravel更加流行和易用,laravel被大批量地用於生產環境,同時這些變動本身,也逐漸使laravel趨於成熟,滿足了大家實際專案的大部分需要。可能沒有了特殊的功能需要,大家也就不會那麼急迫地更新版本,本身laravel 5.4開始的更新變動也相對小了很多。
當然,也可以說大家的專案還都在“升級的過程中”,取決於升級的時間、人力成本等因素,如果可以的話,可能大家都還想升到laravel 5.5,也即第二個LTS版本。
(二)最流行的第三方元件
需要注意的是,接下來的資料樣本,laravel 5.5及以上版本的要小一些,同時laravel自身的核心元件,都被排除在外了。
58%
of apps useguzzlehttp/guzzle
36%
of apps usepredis/predis
34%
of apps uselaravelcollective/html
32%
of apps useleague/flysystem-aws-s3-v3
27%
of apps useintervention/image
25%
of apps usemaatwebsite/excel
24%
of apps usespatie/laravel-backup
23%
of apps uselaravel/horizon
22%
of apps usebugsnag/bugsnag-laravel
21%
of apps uselaravel/socialite
20%
of apps uselaravel/passport
19%
of apps usesentry/sentry-laravel
15%
of apps usespatie/laravel-permission
14%
of apps uselaravel/scout
14%
of apps useleague/csv
流行的開發輔助元件:
- 35% of apps use
barryvdh/laravel-debugbar
- 28% of apps use
barryvdh/laravel-ide-helper
- 19% of apps use
laravel/dusk
- 11% of apps use
laravel/browser-kit-testing
編者點評:
- 值得一提的是,早在兩年前(2016年),這裡面的一些對於初學者來說比較關鍵的第三方元件,在我們的Laravel系列課程裡也都帶領大家使用過了,比如必備的表單元件
laravelcollective/html
,在我們《Laravel實戰:任務管理系統(一)》就跟大家見面了; - 處理圖片必備的
intervention/image
,也在我們《Laravel實戰:任務管理系統(一)》中大量使用,後來出現了很多其他的圖片相關元件,但往往背後也是基於的intervention/image
,比如說近來流行的spatie/laravel-medialibrary
; - 專案備份必備的
spatie/laravel-backup
,是我們在《Laravel&Vue實戰:任務管理系統二》一開始就使用的,當時該元件還名不見經傳; - 關於許可權,可以說一開始首屈一指的是
Zizaco/entrust
,為此呢我們還專門出了免費的公開課《Laravel Entrust角色許可權管理》,但是呢entrust的作者突然從去年開始不怎麼活躍了,於是santigarcor/laratrust
作為entrust的維護版本出現,已經安裝了entrust的可以無縫遷移到laratrust
上,當然這期間另一個許可權元件spatie/laravel-permission
憑藉其強大的活躍也流行起來了,Laravel也推出了自身的許可權功能——Policy。所以許可權這塊,其實用哪個功能就取決於你自己了,都不錯,都可以,那麼如果你許可權這塊感覺有障礙,還是推薦我們的免費的公開課《Laravel Entrust角色許可權管理》,瞭解了原理以後,你可以自行在santigarcor/laratrust
或spatie/laravel-permission
之間選擇。 - 搜尋必備元件
laravel/scout
,這個背後的driver預設基於的是付費服務Algolia
,在國內我們更喜歡開源的Elasticsearch
,laravel/scout
與Elasticsearch
搭配來開發實時搜尋相關的功能,可以看我們的《Laravel & Elastic全文搜尋實戰》課程。 - 關於
guzzlehttp/guzzle
排第一位,可能是因為這兩年api開發開始流行,傳統上我們經常用guzzle來處理http請求,由於資料來源大部分都是5.3及以下的,這個時候passport
與axios
還剛開始流行,所以這一點上,可能後期我們會看到passport
的排名將攀升,axios
因為是前端元件,可能就會被排除在統計資料之外了,但是我們絕不能忽視它的日發流行。
(三)改動最多的檔案——config
config檔案是改動最多的,雖然這很合理,但是呢改動預設的config檔案,也容易導致升級障礙。通常,你可以有其他的方式來處理這些改動,從而使config檔案保持預設的樣子。
這期間一定記得通過ENV
環境變數來改動config檔案的值。很多應用喜歡改變config檔案當中的預設值,而不是設定ENV
,比如假設config/mail.php
:
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'shift@laravelshift.com'),
'name' => env('MAIL_FROM_NAME', 'Laravel _Shift_'),
],
複製程式碼
這樣呢並不好,還是得設定ENV
,讓config檔案保持預設:
'from' => [
'address' => env('MAIL_FROM_ADDRESS', 'hello@example.com'),
'name' => env('MAIL_FROM_NAME', 'Example'),
],
複製程式碼
當你有很多的配置選項需要設定時,再一種方式就是建立你自己的config檔案,比如建立config/system.php
, config/settings.php
,這樣你就不用分別改動多個config檔案了。
(四)不推薦自定義的全域性namespace
使用預設的APP
namespace就好。有9%的apps使用了自定義的namespace,而這個數值應該是0.
如果你更改過namespace,可以這樣來改回:
artisan app:name App
複製程式碼
當然這並不能改回你在資料庫當中,使用到多極對應關係(polymorphic relationships)時的記錄,那個你得自己通過sql query來改變了。
編者按: 這個呢,其實在5.3及以下版本,如果通過artisan app:name
改變了namespace,實際上是會發生很多莫名bug的,所以不推薦出於好奇隨便設定app:name
,除非你知道自己在幹什麼。
(五)apps的目錄結構
接下來是在app
目錄下發現的非laravel官方資料夾:
- 36% of apps contain
app/Models
- 29% of apps contain
app/Services
- 29% of apps contain
app/Helpers
- 25% of apps contain
app/Traits
- 20% of apps contain
app/Rules
- 18% of apps contain
app/Repositories
- 17% of apps contain
app/helpers.php
在laravel 4時代,是預設有app/Models
資料夾的,到了5, laravel作者特意將其刪掉,因為model這個詞在不同的人那裡理解不一樣,有的人認為一個app的model是其整個的業務邏輯,有的人認為model是一些與關係型資料庫進行互動的class,為了不限制大家,乾脆刪掉,讓開發者自己決定該怎麼安置model,也即你可以自己建立app/Models
資料夾,然後遵循MVC框架的傳統方式,也可以“面向業務(service)”,搞一個DDD(Domain-Driven Design)。
當然,這裡手動建立 app/Models
的,一般都是model數量超過了10個。但是,這裡我們想更進一步地,如果model數量超過50個呢?這個時候還是簡單地放在 app/Models
裡,還有特別的意義嗎?
app/Services
資料夾一般放置一些獨立的業務相關的邏輯,可以用來將你的某一部分業務邏輯獨立出來,使業務邏輯模組化,甚至方便後期將其獨立成為單獨的package給其他的專案使用,或者成為一個microservice,關於面向service,或者說package開發,就需要你對laravel底層及其原理有足夠的掌握了,這裡就推薦我們的《Laravel底層核心技術實戰揭祕》
app/Helpers
和app/helpers.php
應該大同小異,前者放置一些輔助功能的class,後者放置一些全域性的helper function,這個在我們的《Laravel&Vue實戰:任務管理系統二》中也給大家介紹過了。
app/Rules
,這個資料夾嚴格來說是laravel本身的,因為它是我們執行artisan make:rule
後產生的,關於laravel 5.5以後建立自定義的驗證規則,也即rule,如果有不懂的同學,可以看我們之前給大家提供的文章:【Laravel 5.5新特性】更方便地建立自定義的資料驗證規則 和 Laravel的unique和exists驗證規則的優化
關於repository,是否放置在app/Repositories
內不是關鍵,關鍵是你是否使用,Repository Design Pattern
可以說是laravel本身以及其眾多第三方元件的命脈之一,Repository Design Pattern
對於你分離業務邏輯,或者開發package,也非常關鍵。repository在laravel剛出來的時候,曾經在國外社群盛極一時,可謂是學laravel必學的,大概在2014年左右可以說是成為一種規範和標準在推行,甚至官方非常簡單的起步專案都要介紹和使用,但是呢國內laravel流行的較晚一些,等到國內開始追逐laravel的時候,國外社群都“懶得提”repository了,加上很多國內材料或教程有意無意地躲避repository,說太複雜了不適合新手,沒必要讓新手學之類的。但其實不是,並不複雜,也並不需要向所謂的新手藏著掖著,否則新手怎麼成為高手?
如果你對repository還感到陌生,不知道是咋回事,那麼請務必看看我們的《Laravel實戰:任務管理系統(一)》,該課程可謂是國內唯一在初學階段就讓你輕鬆嚐鮮Repository Design Pattern
的,讓你在初學階段就打下日後成為高手的根基,當然如果你想真真正正掌握Repository Design Pattern
的全貌,還是推薦我們的《Laravel底層核心技術實戰揭祕》
(六)改造基本的繼承關係
這個一般是指自己額外建立一個BaseController
或者 BaseModel
class,讓它們繼承laravel預設的controller或model,然後自己的具體的controller或者model再繼承這個BaseController
或者 BaseModel
,這期間就可以在BaseController
或者 BaseModel
裡做一些自己的邏輯。
有23%的應用這麼做了,這個呢其實也是不推薦的,這種做法往往在早期的一些國外教程或材料中能看到,但是新近的都不會這麼搞,同時這個應該在國內不是很大的問題。
就比如說model,當我們想擴充套件其功能的時候,更優雅的辦法是使用trait
,而不是寫到BaseModel
裡,這符合我們程式設計設計原則裡常說的“composition over iinheritance”
(七)Facade的濫用
57%的應用濫用,或者說過度使用facade。Facade本身已然是laravel社群內一個極具爭議的話題,或者說是laravel備受非議的一個話題,關於這一點,如果有不瞭解的,可以看看我們之前給大家寫的擴充套件文章PHP中的facade pattern(外觀模式)。那麼大部分的apps亂用facade,無異於火上澆油了。最大的爭議發生在controller
和middleware
當中濫用Request
和Auth
比如一起看一下這個controller
邏輯:
public function store()
{
$data = Request::only('product_id', 'token');
if (Auth::check()) {
$data['email'] = Auth::user()->email;
}
// ...
}
複製程式碼
這裡呢使用Request
來獲取請求資料,使用Auth
來獲取當前使用者。但是呢,無論是controller
還是middleware
,都可以注入一個request
例項:
public function store(Request $request)
{
$data = $request->only('product_id', 'token');
if ($request->user()) {
$data['email'] = $request->user()->email;
}
// ...
}
複製程式碼
這樣就不用呼叫兩個facade,而只通過一個request object。關於方法注入、或者依賴注入、或者依賴解析等,無論是我們的初級課程《Laravel實戰:任務管理系統(一)》,還是我們的高階課程《Laravel底層核心技術實戰揭祕》,都有大量的講解和使用,這些也是掌握laravel、成為高手的關鍵。
當然,如果你有真正學習了我們的《Laravel底層核心技術實戰揭祕》,或者在閱讀PHP中的facade pattern(外觀模式)之餘做足了功夫,那麼你會明白,上面的程式碼也並不能完全解決facade濫用的問題,因為畢竟Request
本身也是一個facade,但是畢竟降低了問題的程度,從而在更好的程式設計和測試過程中,能更大程度地解耦。
(八)View檢視中的query查詢
24%的應用在view中存在資料查詢,這自然是bad practice,檢視層不應該直接互動Model,確保使用Controller來傳遞相關的資料
(九)不要直接呼叫ENV變數值
42%的應用直接呼叫ENV變數。Laravel提供了artisan config:cache
來提高效能,為了充分利用這一功能,不要直接呼叫env資料,而是在config檔案中呼叫。因此,你必須得通過config來間接獲取env數值
(十)CRUD型Controller
77%的應用還沒有采用CRUD型Controller
。所謂CRUD型Controller,指的是將controller裡的方法限制為預設的CRUD這四類,或者說是預設的resourceful controller,也即裡面只有index()
、create()
、store()
、update()
、edit()
、show()
、destroy()
這七個方法,任何多出來的方法都可以重構到單獨的一個controller,這符合坊間“所有的操作其實歸根到底都是CRUD操作”的說法。
當然這一理念呢,還比較新穎,屬於是2017年的laravel國際會議laracon上才開始推薦,所以大部分的應用還沒有真正地實踐,應該國內的開發者也大都對此陌生,不過不要緊,在近期的課程更新中,我們將會在《Laravel底層核心技術實戰揭祕》中給大家介紹類似的一些流行做法。
(十一)Controller內的資料驗證(Validation)
89%的應用在Controller內進行資料驗證,這也是不好的實踐——正如我們在入門課程《Laravel實戰:任務管理系統(一)》裡就講過的,Controller只是一個“指揮者”,它正常來說不負責任何具體的邏輯,所以此處的資料驗證,最好是放到單獨的Request檔案中,正如我們在入門課程裡提倡的那樣。
(十二)Blade相關的命令
71%的應用還沒有使用Laravel提供的一些blade命令。用的最少,但往往最有用的是@auth
,@guest
,@json
,@method
,@csrf
。
當然,這一項所提到的blade命令,其實大都是laravel 5.5才新出的,甚至有些呢文件上也沒有提及,所以大家可能還不熟悉。自然,我們在blade裡面可以使用原生的PHP標籤,但是那樣就有可能沒有充分利用起來laravel給我們提供的便利與優雅,所以blade當中,我們經常也提倡儘可能地不用原生php標籤。
關於blade命令,我們之前也給大家寫過兩篇文章:【Laravel 5.5新特性】可以在blade中自定義if判斷的簡略標籤 和 Laravel Blade中的@each用法
(十三)額外的一些資料分析
最後呢是一些附加的統計資料,注意的是,該項資料樣本相對較小,而且只是限於laravel 5.5及更新版本,該項資料的生成使用的是stefanzweifel/laravel-stats這個元件。
+-------------------+-------+---------+---------------+------------+
| Name | Usage | Classes | Methods/Class | LoC/Method |
+-------------------+-------+---------+---------------+------------+
| Commands | 66% | 6.37 | 2.42 | 9.68 |
| Controllers | 67% | 20.91 | 4.10 | 6.28 |
| Events | 29% | 5.63 | 1.64 | 7.69 |
| Jobs | 31% | 4.11 | 2.36 | 11.84 |
| Listeners | 39% | 5.35 | 1.89 | 5.16 |
| Mails | 39% | 6.72 | 2.06 | 6.71 |
| Middleware | 100% | 4.22 | 0.12 | 4.93 |
| Models | 99% | 17.80 | 3.75 | 3.79 |
| Notifications | 39% | 4.57 | 3.80 | 3.71 |
| Policies | 19% | 5.09 | 3.96 | 2.88 |
| Requests | 58% | 11.04 | 2.07 | 2.52 |
| Resources | 7% | 14.75 | 0.94 | 4.95 |
| Rules | 17% | 2.40 | 3.07 | 2.86 |
| Service Providers | 100% | 6.28 | 1.97 | 4.61 |
| PHPUnit Tests | 100% | 9.96 | 2.02 | 6.63 |
| Dusk Tests | 18% | 5 | 3.00 | 6.67 |
| Browserkit Tests | 3% | 13 | 4.16 | 6.05 |
+-------------------+-------+---------+---------------+------------+
| Total | | 144.54 | 2.18 | 5.72 |
+-------------------+-------+---------+---------------+------------+
複製程式碼
- 相對來講,
Jobs
、Controller
和Events
中的每一個method中包含了最多的程式碼 - 雖然
phpunit test
顯示的是100%的使用,但實際的情況是,大部分都只是laravel預設自帶的示例測試檔案。其他的資料顯示,只有27%的應用裡包含有自定義的測試 - 可能是
laravel-stats
這個元件本身的bug,因為顯示的是67%的應用使用controller,實際上不可能這麼低
結語
看了這些資料,你的laravel學對了嗎?用對了嗎?希望這些資料能給你的laravel使用與學習,提供更好的參考與建議~
值得自豪的是,通過這些資料,可以看到兩年前我們pilishen.com出品的laravel從入門到高手系列課程,兩年後的今天,依然可以說是始終保持在laravel規範使用的前列,因此凡是認真學習了我們系列課程的小夥伴,應該也可以自豪地說自己的laravel用得很優雅、沒問題,在此祝賀你們,同時感謝一往的支援。
這些資料,是過去的兩三年內全球範圍內Laravel使用情況的一個縮影,下一個時代,或者說下一個階段,應該就是Laravel 5.5的時代了。值得慶祝的是,我們的這些系列課程,將於近期統統升級重錄,更新到laravel 5.5及更新的版本,以保證小夥伴們繼續領先下一個時代,下一個未來的兩三年。此次更新,將不只是簡單地版本更新,不是簡單地把已有專案再做一遍,而是一次系統性的經典昇華,升級後的課程將不僅包含本文資料裡提到的這些最佳實踐與建議,而且將包含大量這些資料裡都不曾提到的更優實踐,以此來切實保證我們們的小夥伴們真真正正地領先同行。而且,我們已經上車的小夥伴們,將完完全全免費獲得更新後的所有課程,不止過去,包括將來,相信你們都是國內laravel開發者中的佼佼者~
到現在還沒有上車的小夥伴,你在等什麼呢?~