php讓人難堪。它是如此的破碎,但那些被培訓的業余愛好者,卻對它稱贊不已。php在做一些徽不足道的挽回措施,但我選擇忘記它。
前言
我的脾氣古怪。我會抱怨很多東西。這個星球上大多數技術我都不喜歡。
PHP不僅使用起來尴尬,還有要嘛我想要的不適合,要嘛不是最令人滿意,要嘛違背我的信仰。我可以告訴你關於一門語言,所有我想避免的好方式,所有我喜歡的壞方式。來吧,問吧!談話會很有趣!
php是唯一的例外。幾乎php抽象的所有東西都是支離破碎的。包括語言,框架,整個生態系統都一塌糊塗。我幾乎不能單獨列出咒罵的事情,因為它全身都壞了。每次我打算編輯一堆雜亂如麻的php抱怨清單的時候,我都被一些瑣事打亂,越深入就越會發現其它令人震驚的事情。
php讓人難堪。它是如此的破碎,但那些被培訓的業余愛好者,卻對它稱贊不已。php在做一些徽不足道的挽回措施,但我選擇忘記它。
不過我得讓我的系統擺脫這些東西,也就這樣了,這是最後一次嘗試。
打個比喻
我只是隨口和Mel抱怨下,而她卻堅決讓我發表出來。
我甚至說不出來PHP到底怎麼了,因為—還好。想想你有一個,嗯,工具箱吧。一堆工具。看起來還好,有標准的東西。
你拔除螺絲釘,它怪異的有三個頭。OK,好吧,這對你不太有用,但你猜遲早有天會有用。
你拿出榔頭,被震住了,兩邊都有是尖爪。但它仍然能用,我的意思是,你可以用兩頭的中部斜著敲。
你拿出老虎鉗,但它們沒有鋸齒面。表面平而光滑。這沒多大用,但依然能用,沒什麼。
你可以繼續。工具箱的東西都是怪異和琢磨不定的,但又不能說毫無價值。整體看沒什麼大問題;它的工具都齊全。
現在,想象有很多使用這些工具的木匠,它們和你說:”這些工具有什麼問題呢?我們都用過,它們工作都很好啊!”。工匠們給你展示他們建的房子,每個門都是五邊形的而屋頂是癫倒的。你敲前門,它向內倒榻了,而他們卻抱怨你打破了他們的門。
這就是PHP的問題。
立場
我認為下面的特質對於一門語言的生產力和可用性是重要的,而PHP在大范圍破壞它們。如果你不同意這些,好吧,我無法想像,我們永遠不會達成一致。
一門語言必須是可預見的。它是將人類的思想反映給計算機執行的媒介,因此它的關鍵是,人類對程序的理解實際要正確。
語言必須一致。相似的東西就要看起來相似,不同的就是不同。學習了語言的部分知識,就應能很容易理解剩下的部分。
語言必須簡潔。新語言應該減少繼承舊語言的不好的形式。(我們也可以寫機器碼。)新語言當然應努力避免織入新的特有的形式。
語言必須是可靠的。語言是解決問題的工具;應盡量避免引入新問題。任何”陷阱”都會大量的分散注意力。
語言必須是可調試的。當出錯的時候,程序員必須修正它,我們需要獲得我們想要的幫助。
我的立場是:
PHP到處處充滿驚奇:mysql_real_escape_string,E_ACTUALLY_ALL
PHP不一致:strpos,str_rot13
PHP需要特別形式:error-checkingaroundCAPIcalls,===
PHP古怪:==。for($fooas&$bar)
PHP晦澀:默認無棧跟蹤或fatals,復雜的錯誤報告
我不能就單個問題解釋為什麼它歸為這些類,否則將會沒完沒了。我相信讀者自己會思考。
不要再和我扯這些東西了
我知道很多有利的論點。我也聽到很多反駁的論點。這些都只能讓談話立即停止。不要再跟我扯這些東西了,求你了。
不要和我說”好的開發者能用任何語言寫出好的代碼”,或者壞開發者。.吧啦吧啦。這毫無意義。好的工匠可以用石頭或錘子駕馭釘子,但你見過有多少工匠用石頭的?成為一個好開發者的標准之一就是善於選擇工具。
不要和我說熟記上千個例外和古怪行為是開發者的職責。是的,這在任何系統中都是必要的,因為電腦是傻的。這不意味著,系統能瘋狂的接受而沒有上限。PHP有的只是異常,這是不行的,一旦和語言摔角決斗,你實際編寫程序就要花費更多的努力。我的工具不能為我創建應用產生積極作用。
不要和我說“那就是CAPI的工作方式”。這星球上高級語言存在的目的是什麼,它們能提供的一切僅僅是一些字符串助手函數和一堆C的包裝器?如果是這樣,那就用C!這裡,甚至還有為它准備的CGI庫。
不要和我扯“搞出奇怪的事,是你活該”。如果存在兩個特性,總有一天,某些人會找到一起使用它們的理由。再次強調,這不是C;這裡沒有規范,這裡不需要“未定義行為”。
不要再和我扯Facebook和Wikipedia就用的PHP.我早知道了!它們也能用Brainfuck寫,但只要他們足夠陪明,不斷折騰這些事情,他們總能克服平台的問題。眾所周知,如果使用其它語言編寫,開發時間可能會減少一半或加倍;單獨拿出這些數據毫無意義。
上帝保佑,不要再和我扯任何東西了!如果列出的沒有傷害你的PHP的觀點,無所謂,因此請停止在網上做無意義的爭論,繼續開發高帥富酷的站點來證明我是錯的。
偷偷告訴你:我非常喜歡Python.我也很樂意對它說些你不愛聽的話,如果你真想的話。我並不要求它完美;我只是想揚長避短,總結我想要的最佳東西。
PHP
語言核心
CPAN被稱為“Perl的標准庫”。這並沒有對Perl的標准庫做過多說明,但它蘊含了健壯的核心可以構建強大的東西的思想。
基本原則
PHP最初很明確的是為非程序員設計的(言外之意,非專業程序);根源已經很難脫離。從PHP2.0文檔中挑選出來的對話:
一旦你開始為每個類型區分不同的操作符,你就開始使用語言變得復雜了。例如,你不能為strings使用‘==’,你現在必須用‘eq’。我沒看出這點來,特別是那些類似PHP的腳本語言,它們大多數相當簡單而多數情況下,作為非程序員,只想要一門包含少量基本邏輯語法的語言,而不想付出過多學習曲線。
PHP為保持前進不惜代價。什麼都有比沒有好。
這不是個正確的設計原則。早期的PHP受Perl影響;大量的標准庫參考C使用“out”參數;OO部分的設計像C++和Java.
PHP從其它語言中引入大量的靈感,但對那些熟知其它語言的人,仍然難以理解。(int)看起來像C,但是int並不存在。命名空間使用。新的數組語法使用[key=>value],不同於任何其它語言定義hash字面量的形式。
弱類型(例如,默默的自動在strings/mumbers/等間轉換)是如此的復雜。
少量的新特性以新語法實現;大多數工作通過函數或者看起來像函數的東西完成。除了類的支持,這理所當然的需要新的操作符和關鍵字。
本頁列出的問題都有官方解決方案—如果你想資助Zend修復它們的開源編程語言的話。
路漫漫,其修遠。思考下面的代碼,從PHP文檔的某地方挑出來的。
@fopen('http://example.com/not-existing-file', 'r');
它將做什麼?
如果PHP使用–disable-url-fopen-wrapper編譯,它將不工作。(文檔沒有說,“不工作”是什麼意思;返回null,拋出異常?)
注意這點已在PHP5.2.5中移除。
如果allow_url_fopen在php.ini中禁用,也將不工作。(為什麼?無從得知。)
由於@,non-existentfile的警告將不打印。
但如果在php.ini中設置了scream.enabled,它又將打印。
或者如果用ini_set手動設置scream.enabled.
但,如果error_reporting級別沒設置,又不同。
如果打印出來了,精確去向依賴於display_errors,再一次還是在php.ini.或者ini_set中。
我無法告訴你這個函數調用的行為,如果沒有查看編譯時標志,服務器端配置,和我的程序中的配置的話。這些都是內建行為。
該語言充滿了全局和隱似狀態。mbstring使用全局字符編碼。func_get_arg之類的看起來像正常的函數,但是只對當前正在執行的函數操作。Error/exception處理默認是全局的。register_tick_function設置了一個全局函數去運行每個tick(鉤子?)—-什麼?!
沒有任何線程支持。(不奇怪,因為上面已給出。)加之缺乏內建的fork(下面提到),使得並行編程極其困難。
PHP的某些部分在實踐中會產生錯誤代碼。
json_decode對不正確的輸入返回null,盡管null也是一個JSON解碼的合法對象—該函數極不可靠,除非你每次使用後都調用json_last_error.
如果在位置0處找到,array_search,strpos,和其它類似的函數返回0,但如果都沒有找到的話。會返回false
讓我們稍稍展開最後一部分。
在C中,函數如strpos返回-1,如果未找到。如果你沒檢查這種情況,卻試著以下標使用它,那將可能命中垃圾內存,程序會崩潰。(也許吧,這是C.誰泥馬知道。我確定至少有工具處理它)
話說,Python中,等效的.index方法將拋出一個異常,如果元素沒找到的話。如果你不檢查該情形,程序將崩潰。
在PHP中,該函數返回false.如果你把FALSE作為下標使用,或者用它做其他事情,PHP會默默的將它轉成0,但除了用於===比較。程序是不會崩潰的;它將執行錯誤的邏輯,且無任何警告,除非你記得在每個使用strpos和其它類似函數的地方包含正確的樣版處理代碼。
這真是糟透了!編程語言只是工具;它們是為我服務的。這裡,PHP給我布下了陷阱,等著我跳進去,而我不得不時刻警惕這些無聊的字符串操作和相等