{"action":"created","issue":{"url":"https://api.github.com/repos/hax/hax.github.com/issues/29","labels_url":"https://api.github.com/repos/hax/hax.github.com/issues/29/labels{/name}","comments_url":"https://api.github.com/repos/hax/hax.github.com/issues/29/comments","events_url":"https://api.github.com/repos/hax/hax.github.com/issues/29/events","html_url":"https://github.com/hax/hax.github.com/issues/29","id":111659876,"number":29,"title":"PHP 为什么大小写规则是如此不规则？","user":{"login":"hax","id":159840,"avatar_url":"https://avatars.githubusercontent.com/u/159840?v=3","gravatar_id":"","url":"https://api.github.com/users/hax","html_url":"https://github.com/hax","followers_url":"https://api.github.com/users/hax/followers","following_url":"https://api.github.com/users/hax/following{/other_user}","gists_url":"https://api.github.com/users/hax/gists{/gist_id}","starred_url":"https://api.github.com/users/hax/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/hax/subscriptions","organizations_url":"https://api.github.com/users/hax/orgs","repos_url":"https://api.github.com/users/hax/repos","events_url":"https://api.github.com/users/hax/events{/privacy}","received_events_url":"https://api.github.com/users/hax/received_events","type":"User","site_admin":false},"labels":[{"url":"https://api.github.com/repos/hax/hax.github.com/labels/%E9%BB%91","name":"黑","color":"333333"}],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":2,"created_at":"2015-10-15T16:50:42Z","updated_at":"2015-10-20T18:25:08Z","closed_at":null,"body":"大部分编程语言的符号是 case sensitive 的，少数（如 Basic）是 case insensitive 的。然而 PHP 两种都不是。试验下就会发现，PHP 的函数、方法以及关键字是 case insensitve 的，而变量、常量都是 case sensitive 的。\r\n\r\n至于类，你猜是 sensitive 还是 insensitive？\r\n\r\n#### 我是占位而已\r\n\r\n#### 我是占位而已\r\n\r\n#### 我是占位而已\r\n\r\n#### 我是占位而已\r\n\r\n答案是 insensitive。然而通常我们使用 classloader，如果以大小写不一致的方式使用，则在路径是 case sensitive 的 *nix 环境下，就很容易产生问题了。\r\n\r\n#### 我是占位而已\r\n\r\n好吧，尽管 PHP 再次体现了奇葩，通常 PHP 程序员并不 care 这个问题，绝大多数人遵循“使用和 manual 一致的大小写”的代码风格。\r\n\r\n不过这导致一些很**不友善**的 API 命名，比如 `htmlspecialchars` ，为什么不是 `html_special_chars` 或 `htmlSpecialChars`？\r\n\r\n了解函数是 case insensitive 后，我们知道事实上后者的写法是可行的。实际上最初这个函数（在 PHP2 的文档中）就是以 CamelCase 方式命名的（`HtmlSpecialChars`）。但不知是出于什么原因，（或许是出于*统一*大小写风格？）PHP3 开始，文档中所有函数全部小写了。\r\n\r\n#### 我是占位而已\r\n\r\n但是最初为什么函数被设计为 case insensitive？\r\n\r\nPHP 之父 Rasmus 在[一个访谈](http://www.sitepoint.com/phps-creator-rasmus-lerdorf/)中说：“...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.”\r\n\r\n这里透露出许多信息。其实最初的 PHP 也许比今天更接近一个模板引擎！早期 PHP 就是“宏替换（macro replacement）”，而业务逻辑并不是它的职责。宏替换具体来说是将 HTML 中的某些 tag 替换为 C 写的对应函数的输出。所以[爆栈的这个回答](http://stackoverflow.com/a/6302488/2546547)里说，因为 HTML tag 是 case insensitive 的，所以在查找对应函数时，就按照 case insensitive 的方式了。后来的 PHP 虽然已经变得完全不同，但函数名就一直 case insensitive 了。\r\n\r\n这一原因很有可能是真相。实际上不仅函数，那些早期就有的结构，比如 if / for 之类的关键字，还有 echo、list 之类并非是函数的特殊指令，也都是 case insensitive 的。或许我们应该反过来问，为何在语言大部分元素都是 case insensitive 的情况下，变量名却是 case sensitive 的？\r\n\r\n#### 我是占位而已\r\n\r\n下面我们讨论下 class 。class 的属性和常量是 case sensitive 的，方法是 case insensitive 的。这样和普通变量、常量、函数的大小写情况正好是一致的。（唔！一致性？！）\r\n\r\n问题是类名本身为什么是 insensitive？（从直觉上，类名难道不是更接近常量？）\r\n\r\n#### 我是占位而已\r\n\r\n想一想？\r\n\r\n#### 我是占位而已\r\n\r\n想一想？\r\n\r\n#### 我是占位而已\r\n\r\n想一想？\r\n\r\n#### 我是占位而已\r\n\r\n下面揭晓答案：\r\n\r\n#### 我是占位而已\r\n\r\n因为 PHP 类一开始其构造器并非现在的 `__construct`，而是和类同名的方法。因为方法是 insensitive，所以类名也就是 insensitive 的。（唔！一致性？！）\r\n\r\n#### 我是占位而已\r\n\r\n#### 我是占位而已\r\n\r\n好了，我想现在你可以很自豪的说，自己终于搞清楚 PHP 中各种大小写规则了！然而且慢！\r\n\r\nPHP 有 goto 语句！可以跳转到指定的 label。goto 作为关键字，我们可以肯定它是 case insensitive 的。可是 label 是 sensitive or insensitive 的？\r\n\r\n大家一起来猜一猜罢 :hankey: \r\n\r\n"},"comment":{"url":"https://api.github.com/repos/hax/hax.github.com/issues/comments/149655985","html_url":"https://github.com/hax/hax.github.com/issues/29#issuecomment-149655985","issue_url":"https://api.github.com/repos/hax/hax.github.com/issues/29","id":149655985,"user":{"login":"Fiery","id":2256584,"avatar_url":"https://avatars.githubusercontent.com/u/2256584?v=3","gravatar_id":"","url":"https://api.github.com/users/Fiery","html_url":"https://github.com/Fiery","followers_url":"https://api.github.com/users/Fiery/followers","following_url":"https://api.github.com/users/Fiery/following{/other_user}","gists_url":"https://api.github.com/users/Fiery/gists{/gist_id}","starred_url":"https://api.github.com/users/Fiery/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/Fiery/subscriptions","organizations_url":"https://api.github.com/users/Fiery/orgs","repos_url":"https://api.github.com/users/Fiery/repos","events_url":"https://api.github.com/users/Fiery/events{/privacy}","received_events_url":"https://api.github.com/users/Fiery/received_events","type":"User","site_admin":false},"created_at":"2015-10-20T18:25:08Z","updated_at":"2015-10-20T18:25:08Z","body":"黑的耀眼！"}}