在评论中有些困惑之后
我以为我提出了一个问题.根据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($?->?());
Run Code Online (Sandbox Code Playgroud)
工作正常(即使我的IDE无法显示␀).一些博学的人可以为我清楚这一点吗?我们可以使用任何Unicode吗?如果是这样,从什么时候开始?并不是说我真的想要使用任何东西,A-Za-z_
但我很好奇.
澄清:我不是在使用Regex来验证类名,也不知道PHP内部是否使用了手册中建议的Regex.困扰我的事情(显然是链接问题中的其他人)是为什么像$? = 1
PHP 这样的东西可以使用.PHP6被认为是Unicode版本,但PHP6处于中断状态.但是如果没有Unicode支持,为什么我可以这样做呢?
Art*_*cto 44
这个问题开始在标题中提到类名,但接着是一个包含方法,常量,变量和字段的外来名称的示例.这些实际上有不同的规则.让我们从不区分大小写开始.
这里的一般准则是仅使用可打印的ASCII字符.原因是这些标识符被标准化为它们的小写版本,但是,此转换依赖于区域设置.考虑以下PHP文件,以ISO-8859-1编码:
<?php
function func_á() { echo "worked"; }
func_Á();
Run Code Online (Sandbox Code Playgroud)
这个脚本会起作用吗?也许.这取决于将返回什么,这是依赖于语言环境的:tolower
(
193
)
$ 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字符也可能会在某些区域设置中出现问题.见这个讨论.通过执行仅适用于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中启用它).这允许您声明脚本的编码:
<?php
declare(encoding='ISO-8859-1');
// code here
?>
Run Code Online (Sandbox Code Playgroud)
它还将处理BOM,用于自动检测编码,不会成为输出的一部分.但是,有一些缺点:
最后,存在缺乏规范化的问题 - 相同的字符可以用不同的Unicode代码点表示(与编码无关).这可能导致一些非常难以跟踪的错误.