Laravel 2018使用資料分析——Laravel你用對了嗎?學對了嗎?

pilishen發表於2018-08-14

本文所說的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 use guzzlehttp/guzzle
  • 36% of apps use predis/predis
  • 34% of apps use laravelcollective/html
  • 32% of apps use league/flysystem-aws-s3-v3
  • 27% of apps use intervention/image
  • 25% of apps use maatwebsite/excel
  • 24% of apps use spatie/laravel-backup
  • 23% of apps use laravel/horizon
  • 22% of apps use bugsnag/bugsnag-laravel
  • 21% of apps use laravel/socialite
  • 20% of apps use laravel/passport
  • 19% of apps use sentry/sentry-laravel
  • 15% of apps use spatie/laravel-permission
  • 14% of apps use laravel/scout
  • 14% of apps use league/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/laratrustspatie/laravel-permission之間選擇。
  • 搜尋必備元件laravel/scout,這個背後的driver預設基於的是付費服務Algolia,在國內我們更喜歡開源的Elasticsearchlaravel/scoutElasticsearch搭配來開發實時搜尋相關的功能,可以看我們的《Laravel & Elastic全文搜尋實戰》課程。
  • 關於guzzlehttp/guzzle排第一位,可能是因為這兩年api開發開始流行,傳統上我們經常用guzzle來處理http請求,由於資料來源大部分都是5.3及以下的,這個時候passportaxios還剛開始流行,所以這一點上,可能後期我們會看到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/Helpersapp/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,無異於火上澆油了。最大的爭議發生在controllermiddleware當中濫用RequestAuth

比如一起看一下這個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 |
+-------------------+-------+---------+---------------+------------+
複製程式碼
  • 相對來講,JobsControllerEvents中的每一個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開發者中的佼佼者~

到現在還沒有上車的小夥伴,你在等什麼呢?~

相關文章