再談PHP未來之路

這門語言現在到底處於生命周期的哪個階段?其定位到底是怎樣的?諸如 PHP7、Swoole 的出現到底能給 PHP 帶來怎樣的變化?

當我們拿 PHP 和 java 進行比較的時候,我們往往就兩門語言本身進行比較,如一個是弱類型一個是強類型,一個是數組打天下一個是各種數據結構,甚至連花括號是不是換行寫都會被討論一番。但它們真正的區別並非這些。

當我們談論一門語言的時候,我們是在談它的生態。

“生態”一詞在百度百科上的解釋是:“生態一詞,現在通常是指生物的生活狀態。指生物在一定的自然環境下生存和發展的狀態,也指生物的生理特性和生活習性。生態(Eco-)一詞源於古希臘字,意思是指傢(house)或者我們的環境”。

生態具有如下特點:

  1. 生態是系統,由多個部分組成的完整體;
  2. 生態是開放系統;
  3. 生態具有動態平衡性;
  4. 維持其動態平衡的是源動力,源動力一旦消失,生態即消亡。例如地球生態系統的源動力是太陽能;一旦太陽消失,地球生態則不復存在(想想《流浪地球》);

一種生物的生存狀態不取決於生物自身,而取決於環境,就如恐龍的滅絕並非恐龍自身退化瞭,而是環境改變瞭(或者說恐龍的進化趕不上環境的變化)。

一門語言的興衰不取決於它自身,而取決於環境,具體來說是環境中源動力的強弱。

PHP 應 Web 而生,考查其興衰得考查互聯網的發展。

一般認為互聯網大致經歷瞭三個階段:

  • 階段一:Web1.0 時代,傳統的內容網站,如企業官網、行業門戶網站等,網站自身產生內容,用戶僅查看內容;
  • 階段二:Web2.0 時代,用戶參與內容的創建,如論壇、博客。階段一和階段二都是內容為主,服務為輔(雖然內容的產生方式有所不同);
  • 階段三:移動互聯網時代,信息流、內容與服務並存;

以上三個階段的演化中,用戶參與度越來越高,交互方式越來越豐富,網站流量越來越大。

階段一和階段二是 PHP 的黃金時代,從階段二開始悄悄發生變化,而到瞭階段三,PHP 的黃金時代基本結束。

PHP 這門語言的特點是“簡單、實用”,入行門檻極低,一個編程小白,一周入門,兩天出個網站。一個典型的例子,在數據結構上,不像其他語言有 Array、List、Map、Set,PHP 一個 Array 搞定所有的情況。

PHP 的這種“簡單”是通過犧牲性能為代價的。由於需要簡單,不能有各種類型限制,PHP 必須是動態語言;由於需要簡單,能封裝則封裝,一個 file_x_contents 搞定文件(甚至是網絡)讀寫(該函數是一次性將文件全部加載到內存中,很多人開發不考慮其局限性而用在所有場景,導致內存溢出);由於 Array 承包瞭所有集合型數據結構,其底層需要做各種處理不說,業務層也無法自主選擇更合適的數據結構做針對性的優化(雖然後來 SPL 提供瞭一些基本數據結構)。

PHP 的這種“簡單”還犧牲瞭另一樣東西:程序員的專業素質。PHP 程序員根本不需要去瞭解真正的 Array 和 List 有什麼區別,也不需要去管數據流、緩沖區。從長期來看,這一點是致命的,它使得 PHP 生態中的重要一環很脆弱,很可能是導致 PHP 最終衰落的真正因素。

在 Web1.0 時代,一方面內容產生者是網站自身,另一方面人們隻能通過桌面瀏覽器上網,這些因素使得這個階段絕大部分公司根本不會遇到高並發等性能問題,而且業務的簡單性使得單體應用足以應付一切,因而這個階段 PHP 的缺陷根本不足為患。於是,PHP 的優勢(簡單上手、快速開發)讓這門語言大行其道,什麼 JSP、ASP,根本不是對手。那個時期,人們談論 java、C# 時,基本是在談 ERP,隻有 PHP 才是 Web。

到瞭 2.0 時代,論壇、博客、SNS 的出現,使得用戶創建內容成為可能。由於用戶的積極參與,網站服務器流量相對於 1.0 時代有瞭突增,特別是 SNS 的信息流特性,使得服務器面臨相當的挑戰。不過由於人們仍然是通過 PC 瀏覽器上網,在一定程度上限制瞭使用頻率。這個時期,一些大公司針對 PHP 的性能缺陷做瞭自己的改造,如新浪的各種 c 擴展(yaf、yar 等),facebook 的 HVVM。

在這兩個黃金時代,PHP 世界湧現瞭大量的經典開源項目:WordPress、ecshop、Magento、Discuz、Thinkphp、Yii 等。

徹底結束掉 PHP 黃金時代的是移動互聯網的到來。iphone 改變瞭世界,也改變瞭 PHP 的命運。

移動互聯網時代,人們隨時隨地都能上網,而且幾乎每人一部手機,這帶來的直接效果就是 Web 使用需求出現瞭數量級的增長。另外,移動互聯網時代的另一個特點是內容+服務的一體化,網站不再隻是提供內容,還提供服務(如各種 O2O),因而在使用頻率、交互體驗上的需求都大大增強。

舉個例子,在 1.0 時代,瀏覽器和服務器根本不需要建立長連接,2.0 時代,由於信息流的出現,要求有輪詢機制,但由於當時無論是瀏覽器還是 PHP 都不支持長連接,人們想瞭各種奇淫技巧來實現輪詢。移動互聯網時代,瀏覽器端有瞭 WebSocket,悲劇的是 PHP 本身卻不支持 WebSocket(由於 PHP 的運行機制是一次請求後進程就結束瞭,在語言核心層面無法提供 WebSocket 機制。要想在核心層面支持 WebSocket,必須改造 PHP 的整個運行機制,這幾乎是不可能的)。

至此,一方面 PHP 的性能問題成瞭致命問題,另一方面 PHP 各種“方便”的機制(如由 php-fpm 代替 PHP 腳本自身的常駐進程)滿足不瞭新的場景需求,反倒成瞭桎梏。

在移動互聯、萬物成網的大背景下,微服務應運而生。一般認為微服務本身並非新的概念,早期的 SOA 就有其身影。不過我們談論一個概念本身到底新不新沒有意義(就好比有人認為中國的勾三股四弦五的發現比希臘的畢達哥拉斯定理要早,於是認為該定理是中國人發現的;有人認為中國的陰陽學說含有二進制思想,便認為二進制是中國人發明的),重要的是一個概念何時形成瞭一套完整的體系,以及是如何來解決實際問題的。

微服務架構是相對單體架構來說的。我們先說說微服務的缺點:服務間調用關系復雜、難治理、問題排查復雜、分佈式事務問題等。既然有這麼多缺點,為啥微服務架構當今能大行其道?原因在於單體架構解決不瞭當今面臨的問題:巨大而復雜的業務群、高並發、高可用的系統需求。

微服務給 PHP 帶來什麼呢?

當我們將單體架構拆解成一個個小的服務的時候,我們來考查一下編程語言的選擇,看看 PHP 還是不是最佳選擇:

  • 首先微服務要輕量化。
  • 其次服務要被多個業務端調用,其運行要足夠快。
  • 另外當服務間通信非常頻繁時,通信協議要保持高效,此時 HTTP 協議並非最佳,很多公司傾向於 RPC 協議。
  • 後端服務相對於前面的業務層來說,變動頻率相對要低一些,因而可以適當地犧牲一些開發效率。
  • 要有較成熟的生態和框架支持(成熟的服務治理生態)。

從上面幾點來看,PHP 並非最佳選擇:

  • 傳統的 PHP 架構是 nginx + php-fpm + PHP script,顯然不夠輕量,成百上千個服務都馱著這麼厚厚的一層殼,顯然存在資源浪費問題。
  • PHP 作為腳本語言,由於存在腳本解析消耗,運行速度上趕不上 java、C++ 等靜態語言(不過在 PHP 引入 opcode cache 後情況得到瞭很大改善,而且對於 Web 來說大部分時候都是 I/O 密集型操作,語言本身的性能影響對於絕大部分的公司來說並非主要問題————不過一方面心理學研究表明人類的認知並非完全理性的,人們認為 PHP 比 java 性能差那就是差,不管實際差多少(這就好比我們認為大品牌的東西一定比小品牌的好一樣,編程語言的世界也有品牌效應))。
  • PHP 核心沒有提供現成的 RPC 方案,但可以通過擴展解決,這不是問題。問題是傳統的 PHP 架構(nginx + fpm + script,一次請求完成後工作進程即結束)並不能很好地應用 RPC 通信的優勢。
  • 在生態和框架上,Swoole 貌似是個不錯的選擇,不過 Swoole 的微服務生態目前尚不成熟。
  • 大部分的 PHP 程序員對服務化比較陌生(以及對性能、可靠性等非功能性需求的普遍漠視),上手較慢。

綜合考慮,大部分公司進行服務化的時候,會選用主流靜態語言(java、C++ 以及後起之秀 golang 等)做服務,PHP 更多是來開發中間的業務聚合系統來調用這些服務。

至此,PHP 走下“神壇”,官方那句“PHP 是有史以來最好的語言”永成過去式。

不少人認為,PHP7 和 Swoole 給 PHP 在服務化時代帶來新希望,因為理論上,上面提到的問題 PHP7 和 Swoole 都能較好的解決。

首先 PHP7 帶來瞭極大的性能提升,而且引入強類型、嚴格模式等新特性,使得 PHP 越來越像強類型語言。其次 Swoole 的出現使得 PHP 很容易像 java、go 那樣實現常駐進程服務而不需要依賴 nginx + php-fpm,那麼 由“nginx + php-fpm + script” 的 CGI 模式在服務化時遇到的問題也都得到瞭很好的解決。

那麼,PHP7(以及即將到來的 PHP8 的 JIT 特性)和 Swoole 能給 PHP 帶來第二個黃金時代嗎?

個人認為不能。還是那句話,當我們談論語言時,實際上是在談論生態。

編程語言的生態系統中有個很重要的角色:開發者群體。PHP 自出生時的目標就是“簡單、強大、實用”,實現瞭高度的封裝,讓開發人員專心面對業務。這對工程是好事,對開發人員的成長(以及開發人員生態)來說卻不是。絕大部分的 PHPer 都是業務工程師,幾乎所有工作都是各種業務的 CRUD,很少涉及稍底層的東西,也鮮有關乎設計、架構的。在我周圍的,以及面試遇到的,大部分人根本不瞭解設計模式、數據結構、算法、計算機原理,寫出來的代碼也僅僅是實現瞭業務的功能性需求,很少考慮非功能性需求。另外,在傳統 PHP 的 CGI 模式下,PHP 腳本並不需要考慮自我恢復、自我保護能力如限流、重試、異步等這些在微服務架構下必須考慮的東西。

另外,由於大部分 PHP 程序員平時都是使用 MVC 框架提供的功能實現 CRUD,較少進行對象建模(PHP 並非生來就是面向對象語言,OO 特性是後面加進去的),導致大部分有相當工作經驗的 PHPer 的建模能力都很弱,而微服務的一個重要工作就是對單體項目按業務領域進行拆分、建模,這對 PHPer 來說是個相當大的挑戰。

一個結果是,PHP 程序員普遍專業素質都很弱,根本勝任不瞭復雜的系統架構————這裡的復雜性有兩個層面:技術層面和業務層面。

PHP7 和 Swoole 雖然彌補瞭語言自身的短板,卻彌補不瞭生態中非語言部分的缺陷。有人認為這些缺陷是歷史造成的,不能代表未來。萬物的生命都是連續的、演化的,歷史往往決定瞭未來,雖然身處現在的我們察覺不出。既然 PHP 生態在解決復雜系統問題時不具備優勢,那麼公司就會自然而然地選擇其它更具優勢的生態系統,自此便形成惡心循環(現實中我們遇到的情況是,很多使用 PHP 作為主要語言的中小公司業務規模上來後,不得不從外面聘請架構師,這些架構師大部分都是 java 出身,到公司第一件事就是強行 PHP 轉 java)。

有人可能覺得我是 PHP 黑,畢竟我也沒有做過嚴格的調查來得出上面的結論。但我們可以通過一些現象管中窺豹:

  • 我們可以很容易找到用 java、C++ 寫的設計模式、數據結構與算法方面的暢銷書,卻幾乎找不到 PHP 的。
  • 我們在博客園、CSDN 等技術博客上能看到大量 java、C++、C# 程序員的博客,卻很少看到 PHP 的。
  • 我們看到技術博客上大量 java 程序員在談論各種設計、服務、“三高”架構,卻很少見到 PHP 的。
  • 我們能看到 java、C++ 程序員到處參加各種技術峰會,卻很少見到 PHPer(除瞭 PHP 自己的專項會議)。

你會覺得僅憑 PHP7 與 Swoole 能讓幾乎不談設計模式、不研究數據結構與算法、很少寫博客、很少參加峰會的 PHPer 們開拓出一片服務化的新天地嗎?

PHP 曾經輝煌過,在移動互聯網之前,在單體為王的時代,就像 Delphi 在 Windows 桌面應用為王的時代取得的輝煌一樣。現實的需求是語言生態系統的源動力,當需求發生不可逆轉的改變時,午日終將西傍。

那麼,接下來的問題是:PHP 會很快沒落嗎?

這個問題實際是在問:如今 PHP 是否還在某些場景下具有優勢(即是否還存在現實需求這一源動力)?

PHP 的優勢是簡單、門檻低、實現功能快捷,很適合如下場景:

  • 業務、系統相對簡單,無需服務化;
  • 對性能不是很敏感;
  • 需要快速實現、快速迭代;

在上面這些場景下,微服務(以及 java、C++ 等靜態語言)的優點並不能彌補其缺點,因而推薦使用單體架構或者簡單的服務化(僅僅進行主要服務拆分,並不引入復雜的服務治理體系),這種情形下 PHP 的優勢就顯現出來瞭。一般中小公司正是滿足上面的場景,因而我們發現即使是在移動互聯網時代 PHP 輝煌不再,但仍有大量中小公司采用 PHP 作為核心開發語言。

另外一個事實是,由於所有的大公司都是由小公司成長來的,在公司規模尚小的時候,他們大多也是采用 PHP 作為核心語言的,規模成長後,雖然 PHP 的各種短板阻礙瞭系統的發展,但由於已經有大量的 PHP 項目,完全重新用其他語言開發一遍不太現實,因而他們會采用各種優化手段,比如編寫 PHP 擴展或者將 PHP 編譯成某種靜態語言(如 C++),或者將單體項目中的某些核心功能拆解成服務,單體項目調用後端服務接口————這種情況下,PHP 項目成瞭粘合層。

將 PHP 作為粘合語言的不光是因為歷史遺留問題,還有不少公司新項目也會采用這種架構,這樣既充分利用瞭 PHP 的開發效率(因為粘合層往往比較靠前端,需求變動較頻繁,開發效率是必須要考慮的重要因素),也保證瞭核心服務的性能。

那麼,接下來的問題是,作為快速原型語言和粘合層語言,有沒有其他語言比 PHP 更具優勢?

至少國內不用談 Python 和 RoR(在國外這兩者在 Web 開發上的占有率也不及 PHP),Python 程序員的重心已轉大數據、人工智能瞭, RoR 至少在國內一直不溫不火,在程序員的招聘上比 PHP 要難很多。

nodejs 曾經被認為是 PHP 的最大對手,一個很大的原因是人們認為如果一個公司使用 nodejs 作為後端語言,那麼他隻需要一樣技術棧(前後端都是 js 程序員,而 js 程序員和 PHP 一樣一抓一大把),體現瞭莫大的成本優勢。但事實是 nodejs 並沒有對 PHP 造成根本威脅,未來也不太可能會,原因是持上面觀點的人認為統一技術棧就一定能節約成本,但這是個偽命題。一門語言具有解決某個問題的能力不代表人們就一定會拿它去解決問題,就好比 PHP 也能進行 socket 編程,但很少公司在生產環境大規模使用 PHP 編寫服務器。js 天生就是 Web 前端語言,因而絕大部分 js 程序員都是一直做前端開發的,而前端開發和後端開發模式上有很大不同。前端在很長一段時間都是面向 DOM 編程,即使是有瞭模塊化、React 這些新玩法後,前端開發的重心仍然是事件驅動的交互式編程。後端開發的重心在於建模(即使不對業務進行對象建模,也至少需要面向數據庫進行數據建模)以及業務邏輯的實現,做後端開發,數據庫、Linux 服務器是繞不開的,而這兩者恰恰是大部分前端程序員所缺乏的(換句話說,要招一個既很熟悉前端開發又很熟悉後端開發的 js 程序員是非常難的)。結果就是,招一個 js 程序員用 nodejs 開發後端系統,其成本遠大於招一個 PHPer。

因而,PHP 在未來可預見的很長時期內不會沒落,它會作為中小公司的快速原型語言和大公司的粘合層語言長期存在。

另一個結論是:Python、Ruby On Rails、nodejs 這些語言雖然不會對 PHP 造成根本威脅,但會跟 PHP 一同在 Web 開發領域長期存在————因為它們的源動力是相同的,而 PHP 相對於它們的優勢又不足以完全抹殺掉它們的存在。

總結:

最後,我將上面的分析總結成四個論斷:

  • 論斷一:PHP 在移動互聯網到來之前出現過黃金時期,如今輝煌不再;
  • 論斷二:PHP 在未來可預見的很長時期內不會沒落;
  • 論斷三:後黃金時代 PHP 的定位:中小公司的快速原型語言以及大公司的中間粘合層語言;
  • 論斷四:PHP7 和 Swoole 讓 PHP 在和其他同層級語言(如 Python、RoR、nodejs)的競爭中保持優勢,但無法給 PHP 帶來根本的變化(無法改變 PHP 的定位);

以上就是再談PHP未來之路的詳細內容,更多關於PHP的資料請關註WalkonNet其它相關文章!