標籤:

PHP黑系列之一:PHP 為什麼大小寫規則是如此不規則?

【這是說好的《PHP黑系列》的第一篇。其實文章2015年10月就寫好了,後來我發揮了挖坑不填的傳統,一直沒發到本專欄。今天掙扎一下發出來罷(其實只是搬運一下)。】

大部分編程語言的符號是 case sensitive 的,少數(如 Basic)是 case insensitive 的。然而 PHP 兩種都不是。試驗下就會發現,PHP 的函數、方法以及關鍵字是 case insensitve 的,而變數、常量都是 case sensitive 的。

至於類,你猜是 sensitive 還是 insensitive?

猜一下!

猜一下!

猜一下!

答案是 insensitive。然而通常我們使用 classloader,如果以大小寫不一致的方式使用,則在路徑是 case sensitive 的 *nix 環境下,就很容易產生問題了。

好吧,儘管 PHP 再次體現了奇葩,通常 PHP 程序員並不 care 這個問題,絕大多數人遵循「使用和 manual 一致的大小寫」的代碼風格。

不過這導致一些很不友善的 API 命名,比如 htmlspecialchars ,為什麼不是 html_special_chars 或 htmlSpecialChars?

了解函數是 case insensitive 後,我們知道事實上後者的寫法是可行的。實際上最初這個函數(在 PHP2 的文檔中)就是以 CamelCase 方式命名的(HtmlSpecialChars)。但不知是出於什麼原因,(或許是出於「統一」大小寫風格?)PHP3 開始,文檔中所有函數全部小寫了。

但是最初為什麼函數被設計為 case insensitive?

PHP 之父 Rasmus 在一個訪談中說:「...I then wrote a very simple parser that would pick tags out of HTML files and replace them with the output of the corresponding functions in the C library... The simple parser slowly grew to include conditional tags, then loop tags, functions, etc. At no point did I think I was writing a scripting language. I was simply adding a little bit of functionality to the macro replacement parser. I was still writing all my real business logic in C.」

這裡透露出許多信息。其實最初的 PHP 也許比今天更接近一個模板引擎!早期 PHP 就是「宏替換(macro replacement)」,而業務邏輯並不是它的職責。宏替換具體來說是將 HTML 中的某些 tag 替換為 C 寫的對應函數的輸出。所以爆棧的這個回答里說,因為 HTML tag 是 case insensitive 的,所以在查找對應函數時,就按照 case insensitive 的方式了。後來的 PHP 雖然已經變得完全不同,但函數名就一直 case insensitive 了。

這一原因很有可能是真相。實際上不僅函數,那些早期就有的結構,比如 if / for 之類的關鍵字,還有 echo、list 之類並非是函數的特殊指令,也都是 case insensitive 的。或許我們應該反過來問,為何在語言大部分元素都是 case insensitive 的情況下,變數名卻是 case sensitive 的?

下面我們討論下 class 。class 的屬性和常量是 case sensitive 的,方法是 case insensitive 的。這樣和普通變數、常量、函數的大小寫情況正好是一致的。(唔!一致性?!)

問題是類名本身為什麼是 insensitive?(從直覺上,類名難道不是更接近常量?)

想一想?

想一想?

想一想?

下面揭曉答案:

因為 PHP 類一開始其構造器並非現在的 __construct,而是和類同名的方法。因為方法是 insensitive,所以類名也就是 insensitive 的。(唔!一致性?!)

好了,我想現在你可以很自豪的說,自己終於搞清楚 PHP 中各種大小寫規則了!然而且慢!

PHP 有 goto 語句!可以跳轉到指定的 label。goto 作為關鍵字,我們可以肯定它是 case insensitive 的。可是 label 是 sensitive or insensitive 的?

大家一起來猜一猜罷 ??

【補遺:2年前原文里其實還有一點遺漏,文中提到的 PHP 里的各種構造,其中有一種,實際是又可 case sensitive 又可 case insensitive 的。厲害不?猜猜是哪一種?】

PS. 下一篇《PHP黑系列》什麼時候出?其實很久以前也寫好草稿了,至於哪天發,看心情罷。

註:題圖來自於 Is PHP Case sensitive? What are sensitive words in PHP? - Isrg Rajan ,也是一篇講 PHP 大小寫問題的文章,不過寫得沒我好,嗯。


推薦閱讀:

一個編程語言有可能自己解釋自己嘛?
為什麼國內創造不出很棒的編程語言?
哪些書籍能提高程序員的演算法能力?
為什麼沒有中文的編程?
如果沒有PGO,JIT 編譯相比AOT 編譯有哪些優勢?

TAG:PHP | 编程语言 |