php 7.2 中 define() 定义的全局常量名必须是合法标识符(字母或下划线开头,仅含字母、数字、下划线),不支持命名空间、双冒号、表达式拼接,且大小写敏感性参数已废弃;空格等非法字符会导致定义名与预期不符。

PHP 7.2 中 define() 定义的全局常量,命名必须是合法标识符(字母/下划线开头,后接字母、数字、下划线),且不支持命名空间、不能含双冒号 ::、不能用表达式拼接名称——这是硬性限制,不是风格建议。
为什么不能用 MyClass::CONST 当常量名
因为 define() 只接受字符串字面量作为第一个参数,'MyClass::CONST' 是一个普通字符串,PHP 不会解析它为类常量引用;它会被当作一个名为 MyClass::CONST 的全局常量注册(名字里真带两个冒号),但后续无法用 MyClass::CONST 语法访问——那语法只认类结构里的 const,不认 define() 注册的全局符号。
常见错误现象:
-
define('User::ID', 1); echo User::ID;→Fatal error: Undefined class constant 'ID' -
echo constant('User::ID');→ 能输出1(因为constant()支持字符串解析),但这属于“绕过语法糖”的非常规用法,易读性差、调试困难
define() 名称大小写敏感性在 PHP 7.2 已被弃用
PHP 7.2 开始,define() 的第三个参数 $case_insensitive 已标记为废弃(deprecated),PHP 8.0+ 直接移除。即使你写 define('FOO', 'bar', true),在 7.2 下也能运行,但会触发 E_DEPRECATED 警告,且行为不可靠(部分 SAPI 下可能忽略该参数)。
实际使用建议:
- 一律按大小写敏感处理,不要依赖第三个参数
- 避免定义
foo和FOO两个同名常量(大小写不同),PHP 7.2 会静默覆盖或报错,取决于 Zend 引擎状态 - 检查是否已定义,始终用
defined('FOO'),而不是defined('foo')—— 大小写必须完全一致
命名冲突与作用域混淆风险
全局常量没有命名空间隔离能力,define('STATUS_ACTIVE', 1) 和 define('App\Status::ACTIVE', 1) 是两回事:App\Status::ACTIVE 这种写法在 define() 中是非法的(反斜杠在常量名中不被允许),直接报 Parse error: Invalid character in constant name。
所以真实约束是:
- 常量名只能含 ASCII 字母、数字、下划线(
a-zA-Z0-9_) - 不能以数字开头
- 不能含空格、点号、反斜杠、双冒号、连字符等任何特殊字符
- 推荐用全大写 + 下划线分隔(如
DB_CONNECTION_TIMEOUT),这不是语法要求,但能避免和变量、函数名意外重名
最常被忽略的一点:PHP 7.2 的 define() 常量名不经过任何自动标准化处理——你定义了 ' FOO '(带空格),它就真叫这个名字,defined('FOO') 返回 false,而 defined(' FOO ') 才返回 true。命名时务必手动 trim 并校验格式。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











