【问题标题】:Why illegal constant names doesn't throw errors using define()?为什么非法常量名使用define()不会抛出错误?
【发布时间】:2014-08-26 13:34:05
【问题描述】:

来自Constants 手册:

常量的名称遵循与 PHP 中的任何标签相同的规则。一种 有效的常量名以字母或下划线开头,后跟 任意数量的字母、数字或下划线。作为一个常客 表达式,它会这样表达: [a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*

但是:

 define ("0000X" , 1);

不抛出任何错误或通知,defined 返回 true:

var_dump ( defined ( "0000X" ) ); // true

当然,当尝试使用这个常量时,它会产生:

解析错误:语法错误,意外的 'X' (T_STRING),需要 ',' 或 ';'在第 3 行的 [...][...] 中

另一方面,Const

const 0000X = 2;

在初始化时抛出错误,避免错误使用:

解析错误:语法错误,意外的 '0000' (T_LNUMBER),在第 1 行的 [...][...] 中需要标识符 (T_STRING)

如果有人想看到这一点:

Live example

【问题讨论】:

  • 你知道defineconst 在非常不同的位置进行评估,const 在编译时评估(这就是为什么你不能将它设置为函数定义或其他) ,而define 在执行时被评估(这就是为什么define('START_TIME', microtime(true)); 工作得非常好,尽管它每次运行时(几乎)给出不同的结果)。定义的代码没有做任何事情来验证你的常量(我不知道为什么它没有,但它没有)。
  • define 不应验证输入。当您想使用(无效)令牌时,您将失败。一切都很好,世界也很好,一切都很好,与宇宙同步。
  • 我相信你仍然可以使用defineconstant() 定义的无效常量。这并不是一个好主意……

标签: php constants


【解决方案1】:

这是解析器引擎的限制。在const 中使用时,您本质上会受到代码标记化的限制,因为许多数学表达式要求,以数字开头的标记根据定义被视为数字。这就是您在该用法中看到 unexpected T_LNUMBER 错误的原因。

由于define 是一种以字符串为参数的语言结构,它不会在标记化上出错,因此可以很好地解析和执行它,而它的使用最终在标记化上仍然失败。 define 不检查它的可用性参数对我来说似乎确实是一个错误,但更可能是 PHP 中的一个历史性的怪癖,没有人敢于修复,不知道什么可能会破坏。你可以为它提交一个错误报告,看看 PHP 开发者怎么说。

【讨论】:

    猜你喜欢
    • 2012-03-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-10
    • 2019-12-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多