我以为我问了一个问题。根据PHP手册,有效的类名称应与匹配[a-zA- Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*。但是显然,这不是强制性的,也不适用于其他任何东西:
[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_但我很好奇。
A-Za-z_
澄清: 我不是要使用Regex来验证类名,也不知道PHP是否内部使用了手册中建议的Regex。使我(以及链接问题中的其他人)感到困惑的是,为什么这样的东西$☂ = 1可以在PHP中完全使用。PHP6被假定为Unicode版本,但PHP6处于中断状态。但是,如果没有Unicode支持,那么为什么要这样做呢?
$☂ = 1
这个问题开始在标题中提到类名称,然后继续到一个示例,其中包括方法,常量,变量和字段的外来名称。这些实际上有不同的规则。让我们从不区分大小写的代码开始。
此处的一般准则是仅使用可打印的ASCII字符。原因是这些标识符被规范化为其小写版本,但是,此转换取决于语言环境。考虑以下以ISO-8859-1编码的PHP文件:
<?php function func_á() { echo "worked"; } func_Á();
该脚本可以工作吗?也许。这取决于返回的内容,这取决于语言环境:tolower(193)
tolower
(
193
)
$ LANG = zh_CN.iso88591 php a.php 工作了 $ LANG = en_US.utf8 php a.php 致命错误:在第3行的/home/glopes/a.php中调用未定义的函数func_Á()
因此,使用非ASCII字符不是一个好主意。但是,即使是ASCII字符,在某些区域设置中也可能造成麻烦。看到这个讨论。将来有可能通过做一个仅与ASCII字符一起使用的与语言环境无关的小写字母来解决此问题。
总而言之,如果我们对这些不区分大小写的标识符使用多字节编码,那么我们正在寻找麻烦。不仅仅是我们不能利用不区分大小写的优势。实际上,我们可能会遇到意想不到的冲突,因为使用语言环境规则,组成一个多字节字符的所有字节都会分别变为小写。在将语言环境小写规则应用于每个字节之后,两个不同的多字节字符有可能映射到相同的修改后的字节流表示形式。
由于这些标识符区分大小写,因此问题在这里不太严重。但是,它们只是被解释为字节流。这意味着,如果我们使用Unicode,则必须始终使用相同的字节表示形式。我们不能混合使用UTF-8和UTF-16;我们也不能使用BOM。
实际上,我们必须坚持UTF-8。在ASCII范围之外,UTF-8使用从0xc0到0xfd的前导字节,并且尾随字节在0x80到0xbf的范围内,这在手册允许的范围内。现在假设我们在UTF-16BE编码文件中使用字符“ the”。这将转换为0x01 0x20,因此第二个字节将被解释为空格。
当然,将多字节字符当作单字节字符读取是完全不支持Unicode的。PHP 确实 以“ –enable-zend- multibyte”编译开关的形式提供了一些多字节支持(从PHP 5.4开始,默认情况下已编译多字节支持,但已禁用;您可以zend.multibyte=On在php.ini中启用它。 )。这使您可以声明脚本的编码:
zend.multibyte=On
<?php declare(encoding='ISO-8859-1'); // code here ?>
它还将处理BOM,BOM用于自动检测编码,并且不会成为输出的一部分。但是,有一些缺点:
最后,存在缺乏规范化的问题-相同的字符可能用不同的Unicode代码点表示(独立于编码)。这可能会导致一些非常难以跟踪的错误。