当前位置: 首页 > 面试题库 >

方法,常量,变量和字段的外来名称-错误还是功能?

白浩荡
2023-03-14
问题内容

我以为我问了一个问题。根据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_但我很好奇。

澄清:
我不是要使用Regex来验证类名,也不知道PHP是否内部使用了手册中建议的Regex。使我(以及链接问题中的其他人)感到困惑的是,为什么这样的东西$☂ = 1可以在PHP中完全使用。PHP6被假定为Unicode版本,但PHP6处于中断状态。但是,如果没有Unicode支持,那么为什么要这样做呢?


问题答案:

这个问题开始在标题中提到类名称,然后继续到一个示例,其中包括方法,常量,变量和字段的外来名称。这些实际上有不同的规则。让我们从不区分大小写的代码开始。

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

此处的一般准则是仅使用可打印的ASCII字符。原因是这些标识符被规范化为其小写版本,但是,此转换取决于语言环境。考虑以下以ISO-8859-1编码的PHP文件:

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

该脚本可以工作吗?也许。这取决于返回的内容,这取决于语言环境: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。

实际上,我们必须坚持U​​TF-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中启用它。
)。这使您可以声明脚本的编码:

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

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

  • 性能命中,包括内存和CPU。它以内部多字节编码方式存储脚本的表示形式,这会占用更多空间(并且似乎还会在内存中存储原始版本),并且还会花费一些CPU来转换编码。
  • 通常不编译多字节支持,因此它的测试较少(更多错误)。
  • 在其中编译了支持的安装与未编译支持的安装之间的可移植性问题。
  • 仅指解析阶段; 无法解决 不区分大小写的标识符所概述的问题。

最后,存在缺乏规范化的问题-相同的字符可能用不同的Unicode代码点表示(独立于编码)。这可能会导致一些非常难以跟踪的错误。



 类似资料:
  • 问题内容: 是否可以选择名称为字符串的字段? 我需要这个来让触发器具有像这样的动态字段名称 问题答案: 如果该字符串在您的外部应用程序(如PHP)中,请确保构造MySQL语句。 如果字符串在MySQL表中,则不能。MySQL没有或没有这样的功能。以下是不可能的: 假设您有一个表,其中的字段引用该表中的列名之一。可能会有其他列允许您选择所需的列。 但是,您可以使用PREPARED STATEMENT

  • 问题内容: 我已经学习Python几个月了,对C语言的了解也很少,我想知道是否有人可以帮我解决这个疑问: 变量是名称,值还是存储位置? 例如: 变量x,x的值还是x在内存中的位置? 我正在寻找关于什么是变量的清晰解释。我已经看过Wikipedia上有关变量和此问题的页面,但对我来说都不是很清楚。如果这是一个重复的问题,那么指向正确答案的链接将非常有用。 谢谢! 问题答案: 语句发生了几件事: 创建

  • 为什么在Oracle DB中出现此错误? cx_Oracle。ORA-01036:非法变量名称/数字

  • 我已经创建了一个API,希望将数据插入oracle数据库。但我收到一条错误消息“error:ORA-01036:非法变量名/编号”。我不知道我犯了什么错误。希望能帮我解决这个问题。先谢谢你。 [错误:ORA-01036:非法变量名/编号]{errorNum:1036,偏移量:0}

  • 我正在尝试使用oracledb客户端从nodejs对oracle数据库执行查询,并得到“ORA-01036:非法变量名/编号”。我尝试了多种建议的方法来传递我的变量,但失败了。使用硬代码值的查询。 以下是我的示例代码: 获取"ORA-01036:非法变量名称/数字"或空结果

  • 问题内容: 我正在尝试访问我的一个班级中的班级常量: 如果我有一个变量,该变量持有此常量的名称,如下所示: 我可以通过某种方式访问​​MY_CONST的值吗? 显然不起作用,因为它用于静态属性。变量变量也不起作用。 问题答案: 有两种方法可以执行此操作:使用常量函数或使用反射。 常数函数 常量函数与通过声明的常量以及类常量一起使用: 反思班 第二种更费力的方法是通过反思: