PHP黑系列之一:PHP 為什麼大小寫規則是如此不規則?
大部分編程語言的符號是 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 編譯有哪些優勢?