網(wǎng)站優(yōu)化之PHP并發(fā)性能性能提升104%調(diào)優(yōu)實戰(zhàn)
2019-05-28
2012 年有一篇很火的博客:PHP: a fractal of bad design。作者在文中對 PHP 大張撻伐,幾乎就差說這是反人類的設(shè)計了。第一次讀到此文時,我正在一個惡心的地方處理很多遺留的 PHP 項目。讀完文章時,我開始思考是否要辭職去做一些與編程完全不同的事情。
幸運的是,此后不久我就換了工作,而且 PHP 從 5.* 開始也成長了很多。今天,我想對那些不再使用 PHP 編程,或者被遺留項目困擾的人說點什么。
Spoiler:PHP 跟其他編程語言一樣,都有點自己的小毛病。很多核心函數(shù)的方法簽名不一致,配置設(shè)置仍然不清不楚,仍然有很多開發(fā)人員在寫蹩腳的代碼——因為他們必須這樣做,或者說,他們沒有更好的方法。
但今天,我想說的是 PHP 好的一面:看看 PHP 的成長,共同探討一下如何編寫干凈且可維護的 PHP 代碼。希望大家可以暫時把偏見放進肚子里,哪怕只有幾分鐘。等我說完,你可以把它們再拿出來,但是你一定會驚訝于過去幾年里 PHP 的成長。
快速閱讀
PHP 每年都在積極開發(fā)新版本
自 PHP 5 時代以來,性能至少翻了一番,甚至有可能是曾經(jīng)的三倍
有極其活躍的框架、包和平臺生態(tài)系統(tǒng)
過去幾年增加了很多新特性,語言也在不斷發(fā)展中
像靜態(tài)分析器這樣的工具已經(jīng)成熟,并且會越來越多
更新:有人讓我展示一些代碼示例,這當(dāng)然可以!下面有兩個例子:一個是我比較喜歡的項目,是用 PHP 和 Laravel 語言編寫的;還有一個是我們辦公室維護的幾百個 OSS 包的列表。代碼地址如下:
https://github.com/brendt/aggregate.stitcher.io
https://spatie.be/opensource/packages
那我們開始吧。
歷史背景
首先,我們快速回顧一下 PHP 的發(fā)布周期。現(xiàn)在的 PHP 版本是 7.3,預(yù)計 2019 年底將發(fā)布 7.4,然后下個版本將是 PHP 8.0。
自 5.* 時代之后,其核心團隊努力保持著一年一版本的發(fā)布周期,并在過去四年中成功做到了這一點。
一般來說,每一個新版本都有兩年的有效支持期,然后再用一年來做「安全修復(fù)」。這么做的目的是鼓勵 PHP 開發(fā)人員盡可能使用最新版本,因為每年的小升級比從 5.4 跳到 7.0 版本要容易得多。
PHP 的版本時間表如下:
其中,PHP 5.6 是 5.*時代的最新版本,它的下一個版本就是 7.0。如果您想知道 PHP 6 發(fā)生了什么,可以收聽 PHP 圓桌播客 :
https://www.phproundtable.com/episode/what-happened-to-php-6
了解這些之后,我們可以進一步探討關(guān)于 PHP 的常見誤解了。
PHP 性能
5.* 時代的 PHP 性能充其量也不過是平均水平,但是在 7.0 中,PHP 核心的大部分內(nèi)容都被完全重寫,性能也因此提高了兩到三倍。
光說不練假把式,我們用基準(zhǔn)測試結(jié)果說話。有人對 PHP 的性能進行過基準(zhǔn)測試,這些測試被很好地記錄在了 Kinsta 上:
https://kinsta.com/blog/php-benchmarks/
自從 7.0 出現(xiàn)以后,PHP 的性能一直處于上升期。PHP web 應(yīng)用的性能與其他語言的 web 框架相當(dāng) (在某些情況下甚至更好)。不信可以看看這個通用基準(zhǔn)測試包:
https://github.com/thebenchmarker/webframeworks
PHP 框架雖然沒辦法做到比 C 和 Rust 更好,但是它比 Rails 或 Django 要好得多,并且可以與 ExpressJS 相媲美。
框架和生態(tài)系統(tǒng)
說到框架,PHP 已經(jīng)不再只是 WordPress 了。作為一名專業(yè)的 PHP 開發(fā)人員,我想說的是:WordPress 根本不能代表現(xiàn)在的生態(tài)系統(tǒng)。
一般有兩個主要的 web 應(yīng)用程序框架和一些小框架,比如 Symfony 和 Laravel。當(dāng)然,還有 Zend、Yii、Cake、Code Igniter 等,但是只有這兩種主要的框架才能代表如今的 PHP。
這兩個框架都有一個包含大量包和產(chǎn)品的生態(tài)系統(tǒng)。從管理面板和 CRM 到獨立的軟件包、CI、profiler,眾多如 web sockets 服務(wù)器、隊列管理器、支付集成這樣的服務(wù)...... 可以拿得出手的東西太多了。
不過,這些框架是用于實際開發(fā)的。如果你需要純粹的內(nèi)容管理,像 WordPress 和 CraftCMS 這樣的平臺只會越來越好。
測試 PHP 生態(tài)系統(tǒng)當(dāng)前狀態(tài)的一種方法是查看 Packagist,它是 PHP 的主要 package 存儲庫。它呈指數(shù)級增長,每天大約有 2500 萬次的下載量。公平地說,PHP 生態(tài)系統(tǒng)已經(jīng)不再是過去的小輸家了。
下面的圖表,列出了包和版本的數(shù)量隨時間的變化。
除了應(yīng)用程序框架和 CMS,近年來異步框架也逐步興起。
這些框架和服務(wù)器是用 PHP 或其他語言編寫的,通過這些框架,用戶可以實現(xiàn)真正的異步 PHP。Swoole、Amp 和 ReactPHP 都是很好的例子。
自從我們進入異步世界以來,像 web sockets 和具有大量 IO 的應(yīng)用程序之類的東西已經(jīng)與 PHP 世界息息相關(guān)。
在內(nèi)部郵件列表(內(nèi)核開發(fā)人員討論如何開發(fā)該語言的地方)上也有關(guān)于將 libuv 添加到內(nèi)核的討論。
語言本身
雖然 async 和 await 功能都還不能用,但是在過去幾年里,PHP 語言本身已經(jīng)做了很多改進。下面列出了 PHP 的部分新特性:
Short Closures
Null coalescing operator
Trait
Typed properties
Spread operator
JIT compiler
FFI
Anonymous classes
Return type declarations
Contemporary cryptography
Generators
除了語言特性,我們也應(yīng)該看一下語言的發(fā)展過程。雖然社區(qū)也會提出 RFCs,但一個活躍的核心志愿團隊才是推動語言的發(fā)展的根本。
這些 RFCs 會在「內(nèi)部」郵件列表中進行討論。在添加新的語言特性之前,必須進行投票,獲得至少 2/3 支持的 RFC 才能被寫入內(nèi)核。
大概有 100 個人有投票權(quán),雖然他們不必對每個 RFC 都進行投票。這些人中必須包括核心團隊的成員,因為他們要維護代碼庫。剩下的投票者主要是從 PHP 社區(qū)中挑選出來的,這些人包括 PHP 文檔的維護者、整個 PHP 項目的貢獻者以及 PHP 社區(qū)中的杰出開發(fā)人員。
雖然大多數(shù)核心開發(fā)都是在自愿的基礎(chǔ)上完成的,但是作為核心 PHP 開發(fā)人員之一,Nikita Popov 最近已被 JetBrains 聘用,成為了全職的 PHP 開發(fā)者。另外,Linux 基金會最近也決定投資 Zend framework。這樣的雇傭和收購確保了 PHP 未來發(fā)展的穩(wěn)定性。
工具包
除了程序內(nèi)核本身,PHP 工具包的數(shù)量也在不斷增加。靜態(tài)分析器 Psalm(由 Vimeo 創(chuàng)建)、Phan 和 PHPStan 都是很好的例子。
這些工具可以對 PHP 代碼做靜態(tài)分析,并會報告任何類型的錯誤、可能的 bug 等。在某種程度上,它們的功能幾乎可以趕上 TypeScript 了,不過目前這種語言還無法實現(xiàn)源到源編譯,因此不允許使用自定義語法。
盡管這意味著我們需要依賴 docblock,但 PHP 的最初創(chuàng)建者 Rasmus Lerdorf 確實提到了向內(nèi)核添加靜態(tài)分析引擎的想法。這個想法潛力巨大,但這是一項艱巨的任務(wù)。
為了像 JavaScript 那樣實現(xiàn)源到源編譯,PHP 開發(fā)者們也一直努力在用戶端擴展 PHP 語法。一個名為 Pre 的項目就在做這樣的事:將新的 PHP 語法轉(zhuǎn)換為普通的 PHP 代碼。
雖然 JavaScript 中已經(jīng)實現(xiàn)了這個想法,但是只有提供合適的 IDE 和靜態(tài)分析支持,它才能在 PHP 中工作。這個想法很有意思,但它還需要不斷成長,才有可能成為「主流」。
結(jié)語
說了這么多,你仍然可以吐槽說 PHP 是一種蹩腳的語言。雖然它還是有一些缺點和 20 年的遺留問題,但我仍然熱愛這門語言。
以我的經(jīng)驗來看,我能夠?qū)懗隹煽恳拙S護且高質(zhì)量的軟件。我和客戶對最終的結(jié)果也都是滿意的。
雖然使用 PHP 還會有一些亂七八糟的事情,但如果使用得當(dāng),我認(rèn)為它還是一個不錯的網(wǎng)絡(luò)開發(fā)選擇。