方法,常量,variables和字段的异名 – Bug或Feature?

在评论之后有些混乱

  • 在PHP中有一个字母类名是安全的,例如A,B,C

我以为我提出了一个问题。 根据PHP手册,有效的类名应该与[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]* 。 但显然,这不是强制执行,也不适用于其他任何事情:

 define('π', pi()); var_dump(π); class ␀ { private $␀ = TRUE; public function ␀() { return $this->␀; } } $␀ = new ␀; var_dump($␀ ); var_dump($␀->␀()); 

工作正常(即使我的IDE不能显示␀)。 有些博学的人可以为我清楚吗? 我们可以使用任何Unicode吗? 如果是这样,从什么时候开始? 不是说我实际上只想A-Za-z_但我很好奇。

澄清:我不是在一个正则expression式来validation类名,也不知道如果PHP内部使用它在手册中build议的正则expression式。 让我困惑的东西(显然是链接问题中的其他人)是为什么像$☂ = 1这样的东西可以在PHP中使用。 PHP6被认为是Unicode版本,但是PHP6处于中断状态。 但是,如果没有Unicode支持,为什么我可以这样做呢?

这个问题开始提到标题中的类名,但接下来是一个包含方法,常量,variables和字段的异名的例子。 其实有不同的规则。 让我们从不区分大小写的开始。

不区分大小写的标识符(类和函数/方法名称)

一般的指导原则是只使用可打印的ASCII字符。 原因是这些标识符被标准化为小写版本,但是,这种转换是依赖于区域的。 考虑下面的以ISO-8859-1编码的PHP文件:

 <?php function func_á() { echo "worked"; } func_Á(); 

这个脚本会起作用吗? 也许。 这取决于什么tolower ( 193 )将返回,这是地区相关的:

 $ LANG = en_US.iso88591 php a.php
工作
 $ LANG = en_US.utf8 php a.php

致命错误:调用第3行的/home/glopes/a.php中未定义的函数func_()

因此,使用非ASCII字符不是一个好主意。 但是,即使是ASCII字符也可能在某些地区出现问题。 看到这个讨论 。 通过做一个只能使用ASCII字符的独立于语言环境的低级别,这很可能会在将来得到解决。

总之,如果我们对这些不区分大小写的标识符使用多字节编码,我们正在寻找麻烦。 这不仅仅是我们不能利用不区分大小写的优势。 实际上,我们可能遇到意外的冲突,因为组成多字节字符的所有字节都使用区域设置规则分别变成小写字母。 将区域设置的小写规则应用于每个字节后,可能会有两个不同的多字节字符映射到相同的已修改字节stream表示forms。

区分大小写的标识符(variables,常量,字段)

这里的问题不那么严重,因为这些标识符是区分大小写的。 但是,它们只是被解释为字节stream。 这意味着如果我们使用Unicode,我们必须始终使用相同的字节表示; 我们不能混用UTF-8和UTF-16; 我们也不能使用物料清单。

其实我们必须坚持U​​TF-8。 在ASCII范围之外,UTF-8使用从0xc0到0xfd的引导字节,并且踪迹字节在0x80到0xbf的范围内,这在每个手册允许的范围内。 现在让我们假设我们在UTF-16BE编码文件中使用字符“Ġ”。 这将转换为0x01 0x20,所以第二个字节将被解释为一个空格。

如果将多字节字符看作是单字节字符,那当然根本不支持Unicode。 PHP的编译开关“–enable-zend-multibyte”的forms支持多字节支持(从PHP 5.4开始,默认情况下编译多字节支持,但禁用;可以使用zend.multibyte=On在php.ini中)。 这允许你声明脚本的编码:

 <?php declare(encoding='ISO-8859-1'); // code here ?> 

它还将处理BOM,用于自动检测编码,不会成为输出的一部分。 但是,有一些缺点:

  • 性能命中,内存和CPU。 它以一个内部的多字节编码存储脚本的表示forms,这占用了更多的空间(而且似乎也将原始版本存储在内存中),并且还花费了一些CPU来转换编码。
  • 多字节支持通常不会被编译,所以它的testing(更多的错误)less。
  • 支持编译和不支持的安装之间的可移植性问题。
  • 仅指parsing阶段; 不能解决不区分大小写的标识符概述的问题。

最后,还有一个缺乏标准化的问题 – 同一个字符可能会用不同的Unicode代码点来表示(与编码无关)。 这可能会导致一些很难追踪错误。

你的字符编码为0x80 0x90 0xe2或类似的东西,因此它不匹配你的正则expression式时不解释unicode(工作在单个字节)。

有效的类名以字母或下划线开头,后面跟着任意数量的字母,数字或下划线。 作为正则expression式,可以这样表示:[a-zA-Z_ \ x7f- \ xff] [a-zA-Z0-9_ \ x7f- \ xff] *。

(来自php.net)

从我的理解,目前的PHP版本有一些Unicode支持,但它是不一致的。 正如其他人所build议的,这将在PHP6中解决,该PHP6被取消(不推迟)。 在一天结束的时候,一些“异国情调”的angular色将会起作用,而其他angular色则不会。 显然,正如你所build议的那样,最好坚持A-Za-z0-9_

与此同时,我听说传言说最近重新启动了unicode讨论,可能是从头开始的,因为PHP6中最初的UTF-16提案包含了大量的努力,返回的回报很less。

注意:从我读到的内容来看,下一个主要的PHP版本是PHP 5.4,它可能包含横向集成(traits),数组简写,内置的HTTP服务器以及其他一些非常需要的function。

http://www.mail-archive.com/internals@lists.php.net/msg35720.html