為什麼說php是最糟糕的,也是最好的程式語言

php技術社群發表於2021-11-25

PHP 至少是一門有趣的程式語言。這門語言和用它構建的程式通常屬於兩種設計哲學。在這裡,我所說的並非軟體開發生命週期,如瀑布或敏捷,而是關於軟體應該是什麼樣的基本思想。這些思想被稱為“正確的方式”(The Right Way)和 “更糟就是更好”(Worse is better)。

PHP 又是一門相當奇怪的程式語言。當人們抱怨這門語言“很槽糕”時,他們並沒有說錯。這門語言確實有很多不好的地方。

擱在以前,這門語言還有更多糟糕的問題。嘲笑 PHP 的博文《全面解析 PHP 的槽糕設計》(PHP: a fractal of bad design)確實有幾個正確的觀點,即使這些觀點在九年前發表時就已經過時了。

然而,與此同時,開發人員卻可以利用 PHP 建立結構上“正確”的軟體,並從其他語言中引入被視為良好實踐的哲學。

像 Laminas 和 Symfony 這樣的框架就使用了物件導向程式設計的最佳實踐,使開發者可以用這些框架編寫結構正確的程式碼。

PHP 是怎麼做到這些的?這是因為 PHP 是最糟糕的程式語言。

設計軟體

1991 年,Richard P. Gabriel 發表了一篇文章《Lisp:好訊息,壞訊息,如何贏得大》(Lisp: Good News, Bad News, How to Win Big)。這篇文章的論點是,在軟體設計和壽命方面,“更糟就是更好”的哲學將是更好的選擇。

他之所以得出這一結論,是因為他意識到出現了兩種不同的程式設計流派,他分別將之命名為“麻省理工學院 / 史丹佛風格”(MIT/Standford Style),或者“正確的方式”,以及“新澤西風格”(New Jersey Style)或者“更糟就是更好”。

這兩種哲學的目標相似,但在關鍵領域卻有所不同。兩種風格都側重於哲學理念的四個關鍵領域:簡單性(Simplicity)、正確性(Correctness)、一致性(Consistency)和完整性(Completeness)。

麻省理工學院風格是這樣描述的:

  • 簡單性:設計一定要簡單,不論它的實現還是介面,都一定要簡單。相較而言,讓介面保持簡單更重要。

  • 正確性:在所有可以觀察到的方方面面,設計一定要正確。不要妄想做一個不正確的設計。

  • 一致性:設計一定不能是不一致的。為了確保一致性,你可以略微犧牲簡單性和完整性。一致性和正確性同等重要。

  • 完整性:設計一定要儘可能多地涵蓋重要的情況。所有符合預期的情況一定要被覆蓋到。完整性優先順序應該高於簡單性。

至於新澤西風格,Gabriel 說,它將其目標定義為:

  • 簡單性:設計一定要簡單,不論它的實現還是介面,都一定要簡單。而相較而言,讓實現保持簡單更重要。簡單是最重要的,其他的特性都不如保持簡單更重要。

  • 正確性:在所有可以觀察到的方面,設計一定要正確。但是可以為了簡單而輕微犧牲正確性。

  • 一致性:設計一定不能太過不一致。某些情況下,為了保證簡單可以犧牲一致性。如果將某個不常見的情況引入設計,會導致實現變複雜或者不一致,那麼就不要考慮這種情況。

  • 完整性:設計一定要儘可能多地涵蓋重要的情況。所有符合預期的情況一定要被覆蓋到。完整性可以為任何其他特性讓步。實際上,一旦威脅到實現的簡單性,完整性必須要被犧牲。如果為了保持簡單,可以犧牲一致性來實現完整性;尤其是介面的一致性。

這場爭論的關鍵是用 LISP 和 C 作為例子來說明為什麼“更糟就是更好”。對於 LISP 程式設計師 Gabriel 來說,LISP 是一種比 C 更好的語言,速度和 C 一樣快,而且 Common LISP 的設計、開發和標準化已經花了很多年。

定義該語言的規範吸取了所有不同的 LISP 的精華,而現代開發環境對於 LISP 開發者來說是最好的。

LISP 是正確的方式

LISP 代表了軟體開發的“正確的方式”。LISP 易於互動,你可以透過各種方式與它互動。希望從 Fortran 中呼叫 LISP?

你可以從 Fortran 中呼叫 LISP 並將資料傳入,反之亦然。在使用遺留程式碼時,你可以愉快地使用 LISP 的所有現代“豪華”特性。

LISP 擁有一致的設計,這得益於它的規範。假如你研究一下 Python 這樣的現代語言,規範在提供多個後端和編譯器方面有很大的作用,而且它們都以同樣的方式解釋或編譯程式碼。

這些工具是一流的,1991 年的 LISP 擁有我們今天仍然享受的所有舒適,比如步驟除錯、資料檢查和花哨的編輯器。

作為一種語言,LISP 是完備的。它具有先進的物件導向程式設計層、多重繼承、一流的物件以及函式和型別。LISP 似乎是開發人員心中想要的程式語言。

1991 年,LISP 這麼程式語言可能處於有史以來的最佳狀態。這種技術上的正確性並沒有被實際使用所證實。

LISP 的開發商正在衰退。多年來負面新聞和錯誤定位阻礙了 LISP 的外部聲譽。人們不再將其視為向終端使用者交付軟體的方式。

就開發而言,LISP 往往代表著許多與“大規模預先設計”(Big Design Up Front,BDUF)一樣的理想。

假如你曾經使用過瀑布模型(Waterfall Model)這樣的設計方法,你就會發現一些問題。“正確的方式”非常強調一致性、正確性,並確保考慮到所有能想到的問題。

LISP 本身並非一種單一的語言,而是一個語言家族。儘管 Common LISP 被設計成一種標準,但是 LISP 本身的實現方式是根據需要完成的各種工作而存在的。

Lockless Inc 網站上的一篇文章指出,這種“碎片化”是 LISP 最終失敗的決定因素之一。儘管 LISP 堅持軟體設計的“正確的方式”,但是這種碎片化導致程式碼維護和可移植性都受到了影響。

PHP 是最槽糕的

因此,“更糟就是更好”的軟體首先會被接受,其次它會使使用者期望更少,第三,這些軟體將被不斷改進,直到接近“正確的方法”的程度。——Richard Gabrie

在這一啟示的幾年後,Rasmus Lerdorf 開始研究個人主頁 / 表單直譯器,也就是我們現在所知的 PHP。

PHP/FI 的誕生是因為 Lerdorf 需要維護他的主頁,並與表單和資料庫進行互動。PHP/FI 甚至不是作為一種實際的程式語言設計的,而是作為 C 語言之上的一層指令碼和函式設計的。

PHP 很簡單

設計一定要簡單,不論是它的實現還是介面。

PHP 底層使用了 C 語言,我們之前已經說過,這部分是“最糟糕的”。然而,這也帶來了一些優勢,最重要的是,更簡單的底層語言可以讓它更容易擴充套件。雖然 Hack/HHVM 採用了更多的 C++ 方法,但 PHP 本身仍然是 C 語言。

只需短短几個小時就能學完這門語言的內部結構。Elizabeth Smith 發表過一篇關於 PHP 擴充套件的精彩演講,其中介紹了大量關於 PHP 的內部工作原理。這門語言本身借鑑了其他 C 風格的語言,不僅易於閱讀,並且能夠跟 C 風格的其他語言互相轉換。

PHP 的大多數介面,或者說標準庫,都非常簡單,因為大多數核心功能都只不過是包裝了各種 C 語言庫,然後幾乎原封不動地公開出來。儘管這樣做會導致介面上的一些不一致,但是它為來自 C 或 C++ 的開發者提供了一個熟悉的環境。

PHP 語言非常注重於 Web 開發。將 HTTP 中的概念提取出來並在語言中找到相似的概念通常非常簡單。希望瞭解一個請求的頭資訊嗎?get_headers() 就能滿足你。獲取請求資訊就像讀取  _POST 全域性變數一樣簡單。

PHP 保持了簡單的開發者介面,並且儘可能地保持內部結構的簡單。

PHP(幾乎)是正確的

在所有可以觀察到的方面,設計一定要正確。但是可以為了簡單性而輕微犧牲正確性。

在這裡,PHP 傾向於選擇“簡單”而不是正確。在 HHVM 出現之前,語言的外觀和特性一直沒有得到規範。

Zend 直譯器本身就是規範,並且這門語言的行為方式總是 “正確”的(不包括實際的錯誤)。要想用別的東西代替 PHP 引擎,就必須實現現有引擎的所有特性。

許多核心函式的 LAX 函式引數和返回型別都使得系統的工作更容易。像 strpos() 這樣的函式返回值可以是整型數或布林值,相對於嚴格設計成返回整型數或丟擲異常的方法,處理要稍微容易一些。

看 PHP 語言的發展,幾乎所有新特性都是建立在開發人員需要的基礎上,而不是“因為它錯了所以必須修復”的嚴肅想法。

更多地關注那些嚴格型別和異常錯誤是一種更正確的做事方法。然而,還有一些東西,比如簡短的箭頭函式(arrow function)、屬性和列舉,才是開發者想要用來簡化程式碼的東西。

PHP 不需要一致性

設計一定不能太過不一致。某些情況下,為了保持簡單可以犧牲一致性。

我甚至不打算假裝 PHP 是一致的,但是它的一致性已經足夠了。當涉及到陣列與字串函式時,人們可能會抱怨 needle/haystack 引數順序。

不過,一般而言,陣列函式是一致的,而字串函式也是一致的。與底層 C 庫保持一致比在語言中保持一致要簡單得多。

PHP 在其他方面也足夠一致。正如我在 strpos() 中提到的,PHP 對於遇到錯誤的函式往往會相當一致地返回 FALSE。這未必是正確的,但它卻是一致的。帶下劃線和不帶下劃線的函式名通常都會匹配其基礎庫。

為了簡單起見, PHP 語言犧牲了一致性,但是即使沒有這個規範,它仍然努力在有意義的地方保持一致。

PHP 的完整性符合所需

設計一定要儘可能多地涵蓋重要的情況。

無論何時,在針對 PHP 需求最大的設計任務:編寫 Web 應用程式時,PHP 都是完備的。PHP 從未被設計成一種可以適用於程式設計世界所有問題的語言。

儘管如此,它的簡單性還是使它可以用於 Web 以外的場合。PHP 最初的目的就是為 Web 程式設計提供最基本的功能,這一趨勢一直持續至今。

修改核心語言通常是由開發人員的需求驅動。整個社群提出修改意見,然後經由社群投票,決定新特性被拒絕、改變或者接受。該語言的許多創新都源於快速完成工作的需要。

即便我們吸收了其它語言的功能,也是因為它使我們的開發變得簡單,而很少是因為其他語言做得“更正確”。

今天,你可以用 PHP 開發 Web 應用程式。五年後,你仍然可以用 PHP 開發 Web 應用程式,只不過會增加一些新特性。

但是,語言本身的完整性已經符合今天所需。如果未來有需要,我們可以隨時修改語言或為它新增新功能。

更糟就是更好嗎?

Gabriel 承認,“更糟就是更好”的哲學指的是設計看起來很糟糕,也許不應該作為更好的選擇。唯一的問題是,當他審視這兩種哲學時,與麻省理工學院 /“正確的方式”的設計哲學相比,“更糟就是更好”最終仍然是更靈活的選擇,“具有更好的生存特性”。如果我們看一下 PHP,就可以證實“更糟就是更好”這一觀點。

這些年來,Gabriel 承認他在哪種方式更好之間搖擺不定。PHP 社群一直在爭論我們是應該正確地做事還是繼續簡單地做事。

我們有像 Laminas 這樣的框架,以經典的電腦科學方式構建庫,然後我們有像 Laravel 這樣的框架,關注開發者的體驗和速度。PHP 本身二者兼具。

下次再聽到有人罵 PHP 的時候,就隨他噴去吧。這門語言確實很糟糕。但從許多方面來看,PHP 的長壽和廣泛使用證明了這樣一個事實: 用“正確的方式”做事並不總是比用“最糟糕”的方式做事好。

當有人吐槽你正在使用的框架時,你要明白從長遠來看這並不重要。選擇一種你認為適合自己的設計哲學,並欣然接受這一點:更糟的可能實際上是更好。


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/70009696/viewspace-2844181/,如需轉載,請註明出處,否則將追究法律責任。

相關文章