define() 和 const 都能定义全局常量,但 define() 是运行时函数、支持动态名称和条件定义,const 是编译期解析、性能更高且更安全,但要求 PHP 5.6+(全局)和 7.0+(表达式),且名称必须为字面量。

define() 和 const 哪个能定义全局常量
都能,但行为完全不同:define() 是运行时函数,const 在 PHP 5.6+ 才支持全局作用域(即文件顶层),PHP 7+ 还支持 const 定义数组和表达式。别以为写了 const FOO = 'bar'; 就一定“全局可用”——如果它在函数或类里,就不是全局的。
常见错误现象:const MY_CONST = 42; 写在函数内,结果外面 echo MY_CONST; 报 Notice: Use of undefined constant MY_CONST;或者用 define('MY_CONST', 42); 在 if 分支里,却忘了分支没执行,导致常量根本没定义。
-
define()必须在运行时调用,支持动态名称(如define($name, $value)),适合配置加载、条件注册 -
const(全局)是编译期解析,更快更安全,但名称必须是字面量字符串,不支持变量拼接 - 类内常量只能用
const(如class C { const X = 1; }),不能用define()
define() 的第三个参数 true/false 到底影响什么
这个布尔值控制「是否大小写敏感」,默认 true(敏感)。设成 false 后,define('FOO', 'x', false) 会让 foo、Foo、FOO 全部被识别为同一常量——但这是个陷阱:它只影响常量名的查找,不影响 defined() 或 get_defined_constants() 的行为,而且 PHP 7.3+ 已标记为废弃,未来会移除。
使用场景极少,基本只在遗留系统兼容旧写法时出现。新项目别碰它。
立即学习“PHP免费学习笔记(深入)”;
- 设
false后,echo FOO;和echo foo;都能输出,但defined('foo')返回false(因为底层仍以大写存) - 与
const完全无关——const永远大小写敏感,无此参数 - PHP 8.0+ 不再警告,但行为已不可靠,CI/CD 流水线可能因环境差异突然失败
const 定义全局常量时为什么报 Parse error
大概率是因为用了低版本 PHP:const 支持全局作用域是从 PHP 5.6 开始的。如果你在 PHP 5.4 环境下写 const API_TIMEOUT = 30; 在文件开头,就会直接报 Parse error: syntax error, unexpected 'const'。
另一个常见原因是混用了表达式而没升级到 PHP 7+:const NOW = time(); 在 PHP 7.0+ 合法,在 PHP 5.6 就是语法错误——它只允许标量和数组字面量(PHP 5.6+),而函数调用要等到 PHP 7.0+。
- 检查
php -v,不是看文档,是看实际运行环境 - PHP 5.6 中
const ARR = [1,2];合法;PHP 5.5 中不合法,会报错 - 想兼容老版本?老老实实用
define(),别硬扛const
define() 和 const 在性能与自动加载上有啥区别
差别在编译阶段:const(全局)被 PHP 编译器提前收录进常量表,访问几乎零开销;define() 是函数调用,有栈帧、参数解析、哈希插入等开销,虽然单次微乎其微,但在高频循环中累计可观。
更关键的是自动加载问题:define() 可以放在任意位置(包括 require 的文件里),但 const 如果写在条件块或函数里,就无法被 IDE 或静态分析工具(如 PHPStan)可靠识别——它们依赖 AST 解析,而运行时逻辑会逃逸分析范围。
- Composer 自动加载不会触发
define(),除非你显式 include/require 那个文件;而const文件只要被加载(哪怕没执行到那行),也会被解析(前提是不在条件分支内) - OPcache 对
const优化更好,define()的常量可能被缓存为“运行时注册”,重启 OPcache 后需重新执行代码才能生效 - 别为了“看起来高级”强行用
const替换所有define()——配置中心、环境判断等动态场景,define()更直白可靠
真正容易被忽略的点:常量一旦定义就不能改,但 define() 在重复定义时默认静默失败(除非开启 E_NOTICE),而 const 直接 fatal error。调试时注意错误报告级别是否掩盖了重复定义问题。



















