2019 PHP 框架指南

如果有人現在寫 PHP 不用框架,他不是大神就是新人。

前言

作為一個歷史悠久的程式語言,PHP 也算得上是個現代奇蹟。

多少人指著它罵「速度慢」、「安全性低」、「維護性低」或「可用性侷限」,但要快速弄個成品出來還是一堆人捧著說真香。

框架挑選

原則

  1. 支援 composer:都 2019 年還不支援 composer 真的可以洗洗睡。
  2. 支援 PHP 7+

分類

  1. 包山包海型:Laravel、Phalcon、Symfony
  2. 微框架型:Lumen、Phalcon Micro、Slim
  3. Console Application 型:Laravel Zero、Symfony Console
  4. 特殊應用型:Swoole、Roadrunner

包山包海型

Laravel PHP Framework

  • 最後版本:5.8(2018 年 2 月 26 日發佈)
  • 優點:良好的設計模式與規範、簡明的開發文件、龐大的社群
  • 缺點:過度封裝與部份功能使其效率較低、社群有些高傲(個人感覺)

兩年來打趴其它所有 PHP 框架,以壓倒性的使用者數量聞名的框架。Laravel 封裝多數套件並套用優秀的設計模式與借鑑許多來自 .NET Framework 、Ruby on Rails 或 Java Spring 的特性,使其具備高度易用性。

Laravel 開發文件簡明扼要,雖然實際上在使用時會覺得缺少很多參考性資料(例如一些進階功能,或是佈署的資料基本上都是稍稍帶過,並沒有列在文件中,會依賴去看 API 文件或 Source Code)

Laravel 封裝許多現代網頁應用程式具備的功能,儘管這些功能在 PHP 上可能並不好實現:RESTful Route、Cache、Message Queue、Broadcasting 等;同時也預先安裝現代 PHP 開發者可能會使用到的元件,例如 Symfony 全家餐、Carbon 時間處理、SwiftMailer 信件處理或 Eloquent ORM。

然而,Laravel 為其優秀設計思想此所付出的代價便是效能,舉例而言 $request->user_id 對比於 $request->get('user_id') ,因為使用了魔術方法所以效能明顯低落許多(於 PHP 7.3 中測試約慢 6~9 倍)。

Phalcon

  • 最後版本:3.4.3(2018 年 2 月 25 日發佈)、4.0.0-alpha.2(2018 年 2 月 3 日發佈)
  • 優點:壓倒性的效能(除了 Swoole 或原生寫法)
  • 缺點:需要額外 extension 支援,造成開發時的難度比一般 PHP 要高

Phalcon 是在 Laravel 橫空出世之前使用度/討論度非常高的框架,因為它在 PHP 7 尚未發佈前時的效能可說是傲視群倫,即便到了現在也僅略輸給原生 PHP 一些(不過輸給 Swoole 滿多的)。

然而 Phalcon 是採用 Zephir 編寫,這是 Phalcon 為了提升 PHP extension 撰寫效率時所建立的程式語言,其底層為 C。正因為如此,Phalcon 在做底層 Debugging 時的難度要比傳統 PHP 來得高,且因為需要額外安裝 Phalcon 的 extension,提升開發/佈署時的複雜度。

附註:其實 Zephir 滿推薦學習的,尤其是對 extension 開發有興趣或是想研究 PHP 底層的開發者而言。

Symfony

  • 最後版本:4.2.3(2018 年 2 月 3 日發佈)
  • 優點:支援性全面的元件、詳盡到會迷路的開發文件、良好的社群與公司支援
  • 缺點:開發難度稍高、全家餐體積龐大

Symfony 作為推動現代 PHP 的基石,功不可沒。它擁有全面性的元件(幾乎都可以單獨拿來使用)、龐大的社群及文件支援與數以百萬計的實戰經歷測試。

Composer 以 Symfony Console 為基礎打造、Drupal 及 Joomla 在重構的過程中導入大量的 Symfony Components、Laravel 核心更是全面以 Symfony 為基礎再進行擴展。

Symfony 的設計思想來自於 Java Spring,這也導致原本設計時的體積本身就是龐大的,其效能常常為人所詬病。曾經為了擺脫這個說法,Symfony 推出 Silex 的 micro-framework,有點模仿 Spring Boot 的意味,然而在 Symfony 4.0 推出之後 Silex 即宣告停止維護(官方說法是 Symfony 4.0 之後不再需要 micro-framework,因為可以利用 Symfony Flex 達成目的)。

微框架型

Lumen PHP Framework

  • 最後版本:與 Laravel 同步
  • 優點:擁有 Laravel 的優勢但(據稱)速度更快,載入的元件較少
  • 缺點:套件支持度不一,受到的關注度遠小於 Laravel

作為 Larael 框架的微型化,Lumen 預設載入較少元件使其啟動速度高於 Laravel,且用 nikic/fastroute 取代 symfony/route 加速路由的配對。

在 Symfony 4.1 時,symfony/route 便導入與 nikic/fastroute 相似的路由配對演算法,導致其實現在兩者差異並不會很大,詳細可參閱 New in Symfony 4.1: Fastest PHP Router

Lumen 常常被人檢討的點在於其套件支援度遠不足 Laravel,因為需要視情況另外撰寫 Service Provider,有些套件作者並沒有這個心力去維護。通常來說 Lumen 的使用者應該具備自行設計 Service Provider 的能力才能夠輕鬆使用。

Phalcon Micro

  • 最後版本:與 Phalcon 同步
  • 優點:壓倒性的效能(比 Phalcon 更快)
  • 缺點:需要自行安裝 Phalcon extension,無法使用 Dependency Injection

Phalcon Micro 具備比 Phalcon 更高的效率,算是現代 PHP 開發 + 極致效能時會使用的解決方案。

因為 Phalcon Micro 並未實作 Dispatcher 相關的功能,所以在 Dependency Injection 的功能會無法使用,建議在使用 Phalcon Micro 時要具備良好的開發習慣與設計模式思維。

Slim Framework

  • 最後版本:3.12.0(2019 年 1 月 15 日發佈)
  • 優點:精簡的元件、良好的設計、高度可整併性
  • 缺點:4.0 遲未發佈

Slim Framework 未使用 Symfony 的元件,這讓它的組合看起來相對精簡。且盡量符合 PSR 的各項標準(如使用 PSR7 使其 Request 與 Response 能夠與其它同標準服務對接)

Slim 的作者 Josh Lockhart 同時也是 Modern PHP 的作者,本書有極高的參考價值:我認為每一個 PHP 開發者都應該看過 Modern PHP。

Slim 也整合了很多現代化的元件,例如 Doctrine ORM 或 Eloquent ORM,另外利用 Middleware 的特性整併許多常用的功能,可以參見 Middleware for Slim Framework 3.x

然而 Slim 4.0 遲未發佈(從 2015 年底開始討論 Roadmap 至今),同時也尚未設立時程表,這也導致社群對於這個 Framework 有一些疑慮。

Console Application 型

Laravel Zero

  • 最後版本:5.7.20(2019 年 2 月 10 日發佈)
  • 優點:相似於 Laravel 的使用方法,但它並不是 Laravel 官方的專案
  • 缺點:文件過於簡陋,且 Laravel 既有套件幾乎不支援

Laravel Zero 是個將 Laravel 框架中有關於 Console 的部份剝離出來,並且加入一些 Console 常用的元件所打造成的。

其優勢在於若是擁有 Laravel 的基礎的話,能夠在極短的時間內上手 Laravel Zero。與 Lumen 的困境相同,它的 Service Provider 也要重寫,而且此專案相對於 Laravel/Lumen 而言算是知名度不高,所以幾乎沒有套件作者會為此另外寫 Service Provider。

Symfony Console

  • 最後版本:與 Symfony 同步
  • 優點:想得到的 Console 操作,基本上 Symfony 都已經完美封裝。
  • 缺點:學習曲線有點陡峭,因元件上與 Web 有所不同,API 幾乎都要另外查閱。

作為全家餐的一份子,Symfony 同樣也封裝了 Console 相關操作,無論特殊輸出(如上色、表格、進度條),或是參數設計(全寫、縮寫、說明),甚至是呼叫外部命令都可以達成。

然而其功能全面的代價就是來源於更多更多的元件與看更多更多的文件,不過基本上想在 Console 上實現的功能都可以找一下 Symfony 的文件確定是否已被實作。

特殊應用型

Swoole

Swoole 說是引來 PHP 的革命也不為過。它擁有甚至能與 golang 一較高下的執行效率,並且重新改寫 PHP 的思想。

PHP 一直以來都是「一個 Request 成就一個 Response」,這也導致兩個 Request 間的通訊需要另外的服務(如 Database 或 Message Queue),也因為資料內容不會常駐於記憶體內,這也決定了 PHP 鮮少用於守護行程(daemon process)的撰寫。

然而 Swoole 打破了這個想法,它用了很多 Golang 的思想(如 goroutine)並以原生的 C 語言實現後建立 PHP Extension。
現在,你甚至可以用熟悉的 PHP 啟動一個高效能的 Web Server、WebSocket Server、TCP Server 或 UDP Server,以及如同 Nodejs 那般的非同步請求/回應。

然而 Swoole 的瓶頸也是顯而易見的,部份 Debug 手法的無效化(因為成為一個守護行程,所以中間不能使用 dieexit ,甚至無法使用 xdebug 下斷點),或是需要學習另一個相異於傳統 PHP 的 Debug 手法,例如 GDB。

且 Swoole 相對較新,這也導致一些原生功能並未完全實作,例如對於 PDO 的支援,當然這個是會根據時間改善的,所以並不是太大的問題。

Roadrunner

嚴格來說 Roadrunner 並不是一個 Framework,而是一個以 Golang 實現的 Web Server,且這個 Web Server 是針對 PHP 所設計的。

Roadrunner 取代了兩件東西:Web Server 及 PHP-FPM,並且利用支援 PSR 7 的特性使大部份足夠「現代」的框架可以直接套用其中,最明顯的例子就是 Slim framework 可以無痛直上 Roadrunner。

Laravel/Lumen 也可以使用 Roadrunner,Symfony 的 Bridge 仍在開發中。

Roadrunner 宣稱它擁有極高的效率,而且利用它能夠降低微服務的開發成本(其內建 RPC 的整合,且在容器化時的複雜度底於 PHP-FPM + Nginx)。

與 Swoole 擁有相同的缺點,它在 Debug 時的成本高於傳統 PHP。然而因為它並不會更動任何 PHP 核心,所以傳統 PHP 所能支援的功能幾乎都能夠正常使用。

結論

2019 年應該會是 PHP 穩步向前的一年,在 PHP 7 優化了長年為人詬病的效能問題後,各式因應現代化 DevOps 的手段如雨後春筍冒出。

如果希望快速打造一個產品原型(prototype):

  • 如果是 Server-Side Render,用 Laravel 會是不錯的選擇
  • 如果是 Client-Side Render,用 Slim 配上任何前端框架
不是說 Laravel 不適合 CSR,而是單純對於 API 而言 Laravel 太過龐大。

如果希望打造穩定的產品:

  • Symfony 全家餐或許會很適合

如果希望效率足夠高而且穩定:

  • Server-Side Render: Phalcon
  • Client-Side Render: Phalcon Micro + 任何前端框架

如果希望試試新東西:

  • Swoole 作為非 HTTP 服務(如 WebSocket)
  • Server-Side Render: Roadrunner + Slim/Lumen 作為 API Server
  • Client-Side Render: Roadrunner + Laravel/Symfony 作為全端
  • 用 Zephir 為效能瓶頸寫幾個 extension