答案是优先用const,仅当需在if/foreach/函数内动态定义或用变量拼常量名时才用define;const必须顶层或类中声明、值需编译期确定、支持命名空间和访问修饰符,define可运行时调用、注册全局常量、支持动态名称。

初学者该用 const,不是“能用 define() 就随便选”,而是 const 更早报错、IDE 更认、命名更规范——除非你真需要在 if 里定义,或用变量拼常量名。
const 和 define() 到底该用哪个?
答案很直接:const 是默认选项,define() 是特例工具。
-
const必须写在文件最外层或类内部,值必须是编译期确定的标量或数组(PHP 7.4+ 支持 callable);它不支持在函数、循环、if分支里出现 -
define()可以在任意位置调用,包括条件判断后:if (ENV === 'prod') { define('CACHE_TTL', 3600); } -
define()支持动态常量名:define($name, $value);const不允许,连const $name = 'val'都语法错误 - PHP 7.3+ 已弃用
define('NAME', 'val', true)的第三个参数(大小写不敏感),所以别再依赖它
类中只能用 const,define() 完全无效
类常量不是“全局常量的一种写法”,它是语言级结构,define() 根本无法触达类作用域。
- 类内必须写
const METHOD_GET = 'GET';,不能写define('METHOD_GET', 'GET'),否则报Parse error: syntax error - 访问时必须用
HttpClient::METHOD_GET,不能直接写METHOD_GET - PHP 7.1+ 支持加访问修饰符:
private const API_TIMEOUT = 5000;,define()没这能力
常量名和值的三个高频踩坑点
90% 的初学者报错都卡在这三处,不是语法不会,是规则没吃透。
- 名字以数字开头:如
define('2024_VERSION', '1.0')→ 报Parse error: syntax error;必须改成VERSION_2024 - 值用了未初始化变量:
define('DB_HOST', $host)但$host还没赋值 → 常量值为null,且无警告,后期调试极难定位 - 跨命名空间读全局常量漏反斜杠:
defined('DEBUG')在app\config命名空间下查的是app\config\DEBUG,不是你define('DEBUG', true)那个;得写defined('\DEBUG')
数组常量和资源/对象为什么不能塞进常量?
常量本质是编译期快照,只存“确定值”,不是“运行时引用”。
- PHP 5.6+ 支持
const CONFIG = ['db' => 'mysql'];,但这是编译时深拷贝的数组,不是指针 -
define('DB_CONN', new PDO(...))直接语法错误——对象不能进常量 -
const LOG_FILE = fopen('/tmp/app.log', 'a');同样错,资源(resource)类型被明确禁止,PHP 会报Constant expression contains invalid operations - 如果真要存配置数组,优先用
const(PHP 7.4+ 更稳);老版本 PHP 5.6–7.3 只能靠define()+json_encode()模拟,但记得json_decode(SETTINGS_JSON, true)还原
最易被忽略的一点:const 在命名空间文件里写,等价于“当前命名空间下的常量”,不是全局;想定义真正的全局常量,要么不写命名空间,要么显式用 const \DB_HOST = 'localhost';。这点 IDE 不提示,运行时报 undefined constant 才发现,但已经晚了。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











