这个问题开始在标题中提到类名,然后继续一个示例,其中包括方法、常量、变量和字段的外来名称。这些实际上有不同的规则。让我们从不区分大小写的开始。
不区分大小写的标识符(类和函数/方法名称)
这里的一般准则是仅使用可打印的 ASCII 字符。原因是这些标识符被标准化为其小写版本,但是,此转换取决于区域设置。考虑以下 PHP 文件,以 ISO-8859-1 编码:
<?php
function func_á() { echo "worked"; }
func_Á();
这个脚本会起作用吗?或许。这取决于什么tolower http://linux.die.net/man/3/tolower(
193 http://en.wikipedia.org/wiki/ISO/IEC_8859-1#Codepage_layout)
将返回,这取决于区域设置:
$ LANG=en_US.iso88591 php a.php
worked
$ LANG=en_US.utf8 php a.php
Fatal error: Call to undefined function func_Á() in /home/glopes/a.php on line 3
因此,使用非 ASCII 字符并不是一个好主意。然而,即使是 ASCII 字符在某些语言环境中也可能会出现问题。看这次讨论 http://www.mail-archive.com/internals@lists.php.net/msg46122.html。将来可能会通过执行仅适用于 ASCII 字符的独立于语言环境的小写来解决此问题。
总之,如果我们对这些不区分大小写的标识符使用多字节编码,我们就会自找麻烦。这不仅仅是我们不能利用不区分大小写的优势。实际上,我们可能会遇到意外的冲突,因为组成多字节字符的所有字节都使用区域设置规则单独转换为小写。在将区域设置小写规则应用于每个字节后,两个不同的多字节字符可能会映射到相同的修改后的字节流表示形式。
区分大小写的标识符(变量、常量、字段)
这里的问题不太严重,因为这些标识符区分大小写。然而,它们只是被解释为字节流。这意味着如果我们使用 Unicode,我们必须一致地使用相同的字节表示;我们不能混合使用 UTF-8 和 UTF-16;我们也不能使用 BOM。
事实上,我们必须坚持使用UTF-8。在 ASCII 范围之外,UTF-8 使用从 0xc0 到 0xfd 的前导字节,尾随字节在 0x80 到 0xbf 的范围内,这在手册允许的范围内。现在假设我们在 UTF-16BE 编码文件中使用字符“Ġ”。这将转换为 0x01 0x20,因此第二个字节将被解释为空格。
当然,将多字节字符当作单字节字符来读取是根本不支持 Unicode 的。 PHP确实有一些多字节支持,以编译开关“--enable-zend-multibyte”的形式提供(从 PHP 5.4 开始,默认情况下会编译多字节支持,但已禁用;您可以使用以下命令启用它)zend.multibyte=On
在 php.ini 中)。这可以让您declare http://php.net/manual/en/control-structures.declare.php脚本的编码:
<?php
declare(encoding='ISO-8859-1');
// code here
?>
它还将处理 BOM,用于自动检测编码并且不会成为输出的一部分。然而,也有一些缺点:
- 内存和 CPU 的性能均受到影响。它将脚本的表示形式存储在内部多字节编码中,这会占用更多空间(而且它似乎也将原始版本存储在内存中),并且还花费了一些 CPU 来转换编码。
- 多字节支持通常不会被编译,因此测试较少(更多错误)。
- 已编译支持的安装与未编译支持的安装之间存在可移植性问题。
- 仅指解析阶段;没有解决概述了不区分大小写的标识符的问题。
最后,存在缺乏规范化的问题——相同的字符可能用不同的 Unicode 代码点表示(与编码无关)。这可能会导致一些非常难以跟踪的错误。