PHP是怎么做到最糟糕的編程語(yǔ)言?|?
2021-10-09
作者 |
翻譯 |
規(guī)劃 | 蔡芳芳
本文首發(fā)于本站,經(jīng)原作者授權(quán),由中文網(wǎng)翻譯分享。
我有近 20 年的編程經(jīng)驗(yàn),使用過(guò)各種編程語(yǔ)言進(jìn)行開(kāi)發(fā)。在我以前做過(guò)的很多工作和現(xiàn)在做的工作中,我很高興能夠使用PHP作為核心編程語(yǔ)言。從我第一次使用 PHP 開(kāi)始工作,我聽(tīng)到了對(duì) PHP 的各種抱怨,但同時(shí)我也看到了 PHP 的強(qiáng)大。
PHP 至少是一種有趣的編程語(yǔ)言。這種語(yǔ)言和用它構(gòu)建的程序通常屬于兩種設(shè)計(jì)理念。在這里,我不是在談?wù)?a href='http://fldkw.cn' target='_blank'>軟件開(kāi)發(fā)生命周期,例如瀑布或敏捷,而是關(guān)于軟件應(yīng)該是什么的基本思想。這些想法被稱為“The Way”和“ is ”(是)。
PHP 是另一種相當(dāng)奇怪的編程語(yǔ)言。當(dāng)人們抱怨語(yǔ)言“不好”時(shí),他們并沒(méi)有犯錯(cuò)。這種語(yǔ)言確實(shí)有很多缺點(diǎn)。撇開(kāi),這種語(yǔ)言有更多不好的問(wèn)題。嘲笑 PHP 的博客文章“PHP 糟糕設(shè)計(jì)的綜合分析”(PHP:a of bad)確實(shí)有一些正確的觀點(diǎn),盡管這些觀點(diǎn)在九年前發(fā)布時(shí)已經(jīng)過(guò)時(shí)了。
然而,與此同時(shí),開(kāi)發(fā)人員可以使用 PHP 來(lái)創(chuàng)建結(jié)構(gòu)上“正確”的軟件,并從其他語(yǔ)言中引入被認(rèn)為是良好實(shí)踐的理念。框架喜歡并使用面向?qū)ο缶幊痰淖罴褜?shí)踐,因此開(kāi)發(fā)人員可以使用這些框架編寫(xiě)結(jié)構(gòu)良好的代碼。
PHP 如何做到這一點(diǎn)?這是因?yàn)?PHP 是最糟糕的編程語(yǔ)言。
設(shè)計(jì)軟件
1991年,P.發(fā)表了一篇文章《Lisp: Good News, Bad News, How to Win Big》(Lisp: Good News, Bad News, How to Win Big)。本文的論點(diǎn)是,在軟件設(shè)計(jì)和壽命方面,“越差越好”的理念將是更好的選擇。他得出這個(gè)結(jié)論是因?yàn)樗庾R(shí)到出現(xiàn)了兩個(gè)不同的編程學(xué)校,他將它們命名為“MIT/ ”(MIT/),或者“正確的方式”。,以及“新澤西”或“越差越好”。
這兩種哲學(xué)的目標(biāo)相似,但在關(guān)鍵領(lǐng)域有所不同。兩種風(fēng)格都專注于哲學(xué)的四個(gè)關(guān)鍵領(lǐng)域:簡(jiǎn)單性()、正確性()、一致性()和完整性()。
MIT 風(fēng)格是這樣描述的:
簡(jiǎn)單:設(shè)計(jì)必須簡(jiǎn)單,無(wú)論是實(shí)現(xiàn)還是接口,都必須簡(jiǎn)單。相比之下,保持界面簡(jiǎn)單更重要。
正確性:在所有可觀察的方面,設(shè)計(jì)必須是正確的。不要試圖做出錯(cuò)誤的設(shè)計(jì)。
一致性:設(shè)計(jì)不能不一致。為了確保一致性,您可以稍微犧牲簡(jiǎn)單性和完整性。一致性和正確性同樣重要。
完整性:設(shè)計(jì)必須涵蓋盡可能多的重要情況。必須涵蓋所有符合預(yù)期的情況。完整性的優(yōu)先級(jí)應(yīng)該高于簡(jiǎn)單性。
至于新澤西風(fēng)格,它將其目標(biāo)定義為:
簡(jiǎn)單:設(shè)計(jì)必須簡(jiǎn)單,無(wú)論是實(shí)現(xiàn)還是接口php高級(jí)程序設(shè)計(jì):模式,框架與測(cè)試,都必須簡(jiǎn)單。相比之下,保持實(shí)現(xiàn)簡(jiǎn)單更為重要。簡(jiǎn)單是最重要的,其他功能不如保持簡(jiǎn)單重要。
正確性:設(shè)計(jì)必須在所有可觀察的方面都是正確的。但是為了簡(jiǎn)單起見(jiàn),可以稍微犧牲正確性。
一致性:設(shè)計(jì)不能太不一致。在某些情況下,可以犧牲一致性來(lái)確保簡(jiǎn)單性。如果在設(shè)計(jì)中引入一個(gè)不常見(jiàn)的情況會(huì)導(dǎo)致實(shí)現(xiàn)變得復(fù)雜或不一致,那么就不要考慮這種情況。
完整性:設(shè)計(jì)必須涵蓋盡可能多的重要情況。必須涵蓋所有符合預(yù)期的情況。任何其他特征的完整性都會(huì)受到影響。事實(shí)上,一旦實(shí)現(xiàn)的簡(jiǎn)單性受到威脅,就必須犧牲完整性。如果你想保持簡(jiǎn)單,你可以犧牲一致性來(lái)實(shí)現(xiàn)完整性;尤其是界面的一致性。
這場(chǎng)爭(zhēng)論的關(guān)鍵在于以 LISP 和 C 為例來(lái)說(shuō)明為什么“越糟越好”。對(duì)于 LISP 程序員來(lái)說(shuō),LISP 是一種比 C 更好的語(yǔ)言,和 C 一樣快,而且 LISP 的設(shè)計(jì)、開(kāi)發(fā)和標(biāo)準(zhǔn)化已經(jīng)花費(fèi)了很多年。定義語(yǔ)言的規(guī)范吸取了所有不同 LISP 的精髓,現(xiàn)代開(kāi)發(fā)環(huán)境最適合 LISP 開(kāi)發(fā)人員。
LISP 是正確的方式
LISP 代表了軟件開(kāi)發(fā)的“正確方式”。LISP 易于交互,您可以通過(guò)多種方式與其交互。想從中調(diào)用 LISP?您可以從中調(diào)用 LISP 并傳入數(shù)據(jù),反之亦然。使用遺留代碼時(shí),您可以愉快地使用 LISP 的所有現(xiàn)代“豪華”功能。
由于其規(guī)范,LISP 具有一致的設(shè)計(jì)。如果你學(xué)習(xí)這樣一種現(xiàn)代語(yǔ)言,該規(guī)范在提供多個(gè)后端和編譯器方面有很大的作用,它們都以相同的方式解釋或編譯代碼。這些工具都是一流的,1991 年的 LISP 擁有我們今天仍然享受的所有舒適,例如步進(jìn)調(diào)試、數(shù)據(jù)檢查和花哨的編輯器。
作為一種語(yǔ)言,LISP 是完整的。它具有先進(jìn)的面向?qū)ο缶幊虒樱嘀乩^承,一流的對(duì)象、函數(shù)和類型。LISP 似乎是開(kāi)發(fā)人員想要的編程語(yǔ)言。
1991 年,像 LISP 這樣的編程語(yǔ)言可能處于有史以來(lái)最好的狀態(tài)。這種技術(shù)正確性尚未得到實(shí)際使用的證實(shí)。LISP 的開(kāi)發(fā)者正在減少。多年來(lái),負(fù)面新聞和錯(cuò)誤定位阻礙了 LISP 的外部聲譽(yù)。人們不再將其視為向最終用戶交付軟件的一種方式。
在開(kāi)發(fā)方面,LISP 經(jīng)常代表許多與“Big Up”(BDUF)相同的理想。如果你曾經(jīng)使用過(guò)瀑布模型()這樣的設(shè)計(jì)方法,你會(huì)發(fā)現(xiàn)一些問(wèn)題?!罢_的方式”非常強(qiáng)調(diào)一致性和正確性,并確??紤]到所有可以想到的問(wèn)題。
LISP 本身不是一種語(yǔ)言,而是一個(gè)語(yǔ)言家族。雖然 LISP 是作為標(biāo)準(zhǔn)設(shè)計(jì)的,但 LISP 的實(shí)現(xiàn)本身是根據(jù)需要完成的各種任務(wù)而存在的。Inc網(wǎng)站的一篇文章指出,這種“碎片化”是導(dǎo)致LISP最終失敗的決定性因素之一。盡管 LISP 堅(jiān)持軟件設(shè)計(jì)的“正確方式”,但這種碎片化已經(jīng)影響了代碼的維護(hù)和可移植性。
C 和 Unix 是錯(cuò)誤的方式
同時(shí),由于Unix的出現(xiàn),C語(yǔ)言逐漸成為軟件開(kāi)發(fā)的首選方法。C語(yǔ)言是為Unix設(shè)計(jì)的,Unix是為C語(yǔ)言設(shè)計(jì)的。它的開(kāi)發(fā)人員與麻省理工學(xué)院的 LISP 及其作者有著不同的設(shè)計(jì)立場(chǎng)。
1972 年,C 語(yǔ)言被設(shè)計(jì)為一種簡(jiǎn)單的語(yǔ)言。到1991年,它發(fā)生了一些變化,但C語(yǔ)言的基本原理沒(méi)有改變。添加了一些功能以滿足開(kāi)發(fā)人員和 Unix 的需求。因?yàn)檎Z(yǔ)言非常簡(jiǎn)單,所以很容易編寫(xiě)編譯器和程序。雖然這種語(yǔ)言并不妨礙你進(jìn)行復(fù)雜的編程,但與 LISP 相比,C 語(yǔ)言估計(jì)只有程序員需要的 50-80% 的功能。
但是,C語(yǔ)言具有很強(qiáng)的可移植性。與 LISP 軟件和環(huán)境中常用的硬件相比,它還可以在低功耗硬件上運(yùn)行。這個(gè)因素使得在更廣泛的機(jī)器上編譯和運(yùn)行軟件成為可能。C語(yǔ)言和Unix易于使用。我認(rèn)為 Unix 和 C 語(yǔ)言會(huì)像病毒一樣流行起來(lái)。
在設(shè)計(jì)和構(gòu)建 Unix 的過(guò)程中,開(kāi)發(fā)了 C 語(yǔ)言。由于貝爾實(shí)驗(yàn)室不允許正式進(jìn)入計(jì)算機(jī)領(lǐng)域,Unix 也可以很容易地分發(fā)給各種不同的用戶。這些用戶幫助修補(bǔ) Unix 以滿足他們自己的需求。這些補(bǔ)丁可以根據(jù)需求進(jìn)行集成,無(wú)需提前考慮這些需求。
與 LISP 不同,C 語(yǔ)言至今仍被廣泛使用。雖然PHP等高級(jí)解釋語(yǔ)言是很多開(kāi)發(fā)者的首選,但是這些高級(jí)語(yǔ)言很多都是用C語(yǔ)言開(kāi)發(fā)的。即使像 Rust 這樣的競(jìng)爭(zhēng)對(duì)手開(kāi)始出現(xiàn),在小型、低功耗設(shè)備上運(yùn)行的能力仍然是 C 語(yǔ)言的優(yōu)勢(shì)。
PHP 是最糟糕的
因此,“越差越好”的軟件首先會(huì)被接受,其次,它會(huì)讓用戶期望更少,其次,這些軟件會(huì)不斷改進(jìn),直到接近“正確的方式”。
——
這個(gè)啟示幾年后,我開(kāi)始研究個(gè)人主頁(yè)/表單解釋器,也就是我們現(xiàn)在所知道的 PHP。PHP/FI 的誕生是因?yàn)樾枰S護(hù)他的主頁(yè)并與表單和數(shù)據(jù)庫(kù)進(jìn)行交互。PHP/FI 甚至不是作為一種實(shí)際的編程語(yǔ)言設(shè)計(jì)的,而是作為 C 語(yǔ)言之上的腳本和函數(shù)層。
PHP很簡(jiǎn)單
無(wú)論是實(shí)現(xiàn)還是接口,設(shè)計(jì)都必須簡(jiǎn)單。
PHP在底層使用了C語(yǔ)言,正如我們之前所說(shuō)php高級(jí)程序設(shè)計(jì):模式,框架與測(cè)試,這部分是“最糟糕”的部分。但是,這也帶來(lái)了一些優(yōu)勢(shì),最重要的是,更簡(jiǎn)單的底層語(yǔ)言可以使其更容易擴(kuò)展。盡管 Hack/HHVM 使用了更多的 C++ 方法,但 PHP 本身仍然是 C 語(yǔ)言。
您可以在短短幾個(gè)小時(shí)內(nèi)了解語(yǔ)言的內(nèi)部結(jié)構(gòu)。我做了一個(gè)關(guān)于 PHP 擴(kuò)展的精彩講座,介紹了很多 PHP 的內(nèi)部工作原理。這種語(yǔ)言本身借鑒了其他 C 風(fēng)格的語(yǔ)言,不僅易于閱讀,而且可以與其他 C 風(fēng)格的語(yǔ)言相互轉(zhuǎn)換。
PHP的大部分接口,或者說(shuō)標(biāo)準(zhǔn)庫(kù),都非常簡(jiǎn)單,因?yàn)榇蟛糠趾诵墓δ軣o(wú)非就是封裝了各種C語(yǔ)言庫(kù),然后幾乎完好無(wú)損的公開(kāi)。雖然這樣做會(huì)導(dǎo)致界面上的一些不一致,但它為來(lái)自 C 或 C++ 的開(kāi)發(fā)人員提供了一個(gè)熟悉的環(huán)境。
PHP 語(yǔ)言非常專注于 Web 開(kāi)發(fā)。提取 HTTP 中的概念并找到語(yǔ)言中的相似概念通常非常簡(jiǎn)單。想知道一個(gè)請(qǐng)求的頭部信息嗎?() 可以滿足你。獲取請(qǐng)求信息就像讀取 $_GET 和 $ 全局變量一樣簡(jiǎn)單。
PHP 維護(hù)了一個(gè)簡(jiǎn)單的開(kāi)發(fā)人員界面,并使其內(nèi)部結(jié)構(gòu)盡可能簡(jiǎn)單。
PHP(幾乎)是正確的
在所有可觀察的方面,設(shè)計(jì)必須是正確的。但是為了簡(jiǎn)單起見(jiàn),可以稍微犧牲正確性。
在這里,PHP 傾向于選擇“簡(jiǎn)單”而不是正確。在 HHVM 出現(xiàn)之前,語(yǔ)言的外觀和特性還沒(méi)有被標(biāo)準(zhǔn)化。Zend 解釋器本身就是規(guī)范,語(yǔ)言的行為方式總是“正確的”(不包括實(shí)際錯(cuò)誤)。如果你想用別的東西替換 PHP 引擎,你必須實(shí)現(xiàn)現(xiàn)有引擎的所有功能。
許多核心函數(shù)的 LAX 函數(shù)參數(shù)和返回類型使系統(tǒng)的工作更容易。像 () 這樣的函數(shù)的返回值可以是整數(shù)或布爾值。與嚴(yán)格設(shè)計(jì)為返回整數(shù)或拋出異常的方法相比,它更容易處理。
縱觀PHP語(yǔ)言的發(fā)展,幾乎所有的新特性都是基于開(kāi)發(fā)者的需求,而不是“因?yàn)殄e(cuò),所以必須修復(fù)”的嚴(yán)肅想法。更多地關(guān)注那些嚴(yán)格的類型和異常錯(cuò)誤是一種更正確的做事方式。但是,仍然有一些東西,例如短箭頭函數(shù)()、屬性和枚舉,開(kāi)發(fā)人員希望簡(jiǎn)化代碼。
PHP不需要一致性
設(shè)計(jì)不能太不一致。在某些情況下,可以犧牲一致性來(lái)保持簡(jiǎn)單。
我什至不打算假裝 PHP 是一致的,但它的一致性就足夠了。當(dāng)涉及到數(shù)組和字符串函數(shù)時(shí),人們可能會(huì)抱怨 / 參數(shù)順序。不過(guò)一般來(lái)說(shuō),數(shù)組函數(shù)是一致的,字符串函數(shù)也是一致的。與底層 C 庫(kù)保持一致比在語(yǔ)言中保持一致要簡(jiǎn)單得多。
PHP 在其他方面也足夠一致。正如我在 () 中提到的,PHP 傾向于相當(dāng)一致地返回遇到錯(cuò)誤的函數(shù)。這可能不正確,但它是一致的。帶下劃線和不帶下劃線的函數(shù)名稱通常與基礎(chǔ)庫(kù)匹配。
為簡(jiǎn)單起見(jiàn),PHP 語(yǔ)言犧牲了一致性,但即使沒(méi)有這個(gè)規(guī)范,它仍然努力在有意義的地方保持一致。
PHP完整性滿足要求
設(shè)計(jì)必須涵蓋盡可能多的重要情況。
每當(dāng) PHP 是最苛刻的設(shè)計(jì)任務(wù):編寫(xiě) Web 應(yīng)用程序時(shí),PHP 就完成了。PHP 從來(lái)沒(méi)有被設(shè)計(jì)為一種可以應(yīng)用于編程世界中所有問(wèn)題的語(yǔ)言。盡管如此,它的簡(jiǎn)單性使其可以在 Web 之外使用。PHP 的最初目的是為 Web 編程提供最基本的功能,這種趨勢(shì)一直持續(xù)到今天。
修改核心語(yǔ)言通常是由開(kāi)發(fā)人員的需求驅(qū)動(dòng)的。整個(gè)社區(qū)提出修正案,然后通過(guò)社區(qū)投票,決定拒絕、更改或接受新功能。該語(yǔ)言的許多創(chuàng)新源于快速完成工作的需要。即使我們吸收了其他語(yǔ)言的特性,也是因?yàn)樗屛覀兊拈_(kāi)發(fā)更容易,很少是因?yàn)槠渌Z(yǔ)言“做得更正確”。
今天,您可以使用 PHP 開(kāi)發(fā) Web 應(yīng)用程序。五年后,您仍然可以使用 PHP 開(kāi)發(fā) Web 應(yīng)用程序,但會(huì)添加一些新功能。然而,語(yǔ)言本身的完整性已經(jīng)滿足了今天的需求。將來(lái)如有必要,我們可以隨時(shí)修改語(yǔ)言或?yàn)槠涮砑有鹿δ堋?/p>
越差越好嗎?
承認(rèn)“越糟越好”的理念是指設(shè)計(jì)看起來(lái)很糟糕,也許不應(yīng)該是更好的選擇。唯一的問(wèn)題是,當(dāng)他審視這兩種哲學(xué)時(shí),與MIT/“正確方式”的設(shè)計(jì)哲學(xué)相比,“更糟更好”最終仍然是一個(gè)更靈活的選擇,“具有更好的生存特性”。如果我們查看 PHP,我們可以確認(rèn)“更糟更好”的觀點(diǎn)。
多年來(lái),他承認(rèn)自己在哪種方式更好之間搖擺不定。PHP 社區(qū)一直在爭(zhēng)論我們應(yīng)該正確地做事還是繼續(xù)簡(jiǎn)單地做事。我們有這樣的框架,我們以經(jīng)典的計(jì)算機(jī)科學(xué)方式構(gòu)建庫(kù),然后我們有這樣的框架,專注于開(kāi)發(fā)人員的體驗(yàn)和速度。PHP 本身兩者都有。
下次聽(tīng)到有人罵 PHP 就讓他噴吧。這種語(yǔ)言真的很糟糕。但在許多方面,PHP 的長(zhǎng)久和廣泛使用證明了這樣一個(gè)事實(shí),即以“正確的方式”做事并不總是比以“最壞”的方式做事更好。當(dāng)有人抱怨你使用的框架時(shí),你必須明白從長(zhǎng)遠(yuǎn)來(lái)看這無(wú)關(guān)緊要。選擇一種您認(rèn)為適合自己的設(shè)計(jì)理念,并接受這一點(diǎn):實(shí)際上可能越糟越好。
關(guān)于作者:
有多個(gè)角色:丈夫、父親、作家、演講者、播客主持人和 PHP 開(kāi)發(fā)人員。在他 12 年的編程生涯中,他使用了許多不同的框架和語(yǔ)言,但他一天中的大部分時(shí)間都在使用 PHP 和 PHP。他是《for(暫無(wú)中文版)》一書(shū)的作者,與公司和開(kāi)發(fā)人員合作,將容器集成到他們的工作流程中。
原文鏈接: