define() 是函数,支持运行时动态定义且无视命名空间;const 是语言结构,编译期解析、更快更严格,支持命名空间和类常量,但检查需用限定名。

define() 和 const 定义常量的区别在哪
PHP 里定义常量有两种主流方式:define() 是函数式调用,const 是语言结构。前者可在运行时动态执行(比如放在 if 分支里),后者在编译期解析,更快更严格。
但注意:const 在 PHP 5.6+ 才支持表达式(如 const MAX = 10 * 2;),而 define() 从一开始就能接受变量值(define('PATH', __DIR__ . '/src');)。
-
define()不支持命名空间内直接定义类常量(得用MyClass::CONST_NAME形式间接设) -
const在类中定义成员常量必须加public(PHP 7.1+ 允许省略,但不推荐) - 全局作用域下用
const定义的常量,名称不区分大小写(仅限老版本兼容行为;PHP 7.4+ 已废弃该特性,实际应始终视为大小写敏感)
常量的作用域是否受 namespace 影响
是的,而且影响很直接。用 const 在命名空间内定义的常量,属于该命名空间,引用时需带完整前缀,比如:
namespace MyApp; const VERSION = '2.1'; // 外部要用 MyAppVERSION 或 use const MyAppVERSION;
而 define() 默认注册到全局空间,无论当前 namespace 是什么,它都无视命名空间——除非你手动拼上命名空间前缀:
namespace MyApp;
define('MyAppDEBUG', true); // 这样才等效于命名空间常量
- 不显式加命名空间前缀的
define('DEBUG', true),等同于define('DEBUG', true)在全局,任何地方都能直接用DEBUG - 类内部用
const定义的是类常量,只能通过self::、static::或ClassName::访问,不受外部 namespace 影响
为什么 defined() 检查不到某些 const 常量
常见原因是:你在类或命名空间里用了 const,却用 defined('MyConst') 去查——这会失败,因为 defined() 只检查“普通常量”(即通过 define() 或全局 const 定义的),不识别类常量或命名空间常量。
- 查类常量得用
defined('MyClass::MY_CONST')(PHP 5.6+ 支持这种语法)或反射(new ReflectionClass('MyClass'))->getConstant('MY_CONST') !== null - 查命名空间常量,必须传完整限定名,如
defined('MyApp\VERSION')(注意双反斜杠转义) -
defined()对大小写敏感,defined('version')查不到const VERSION
常量能存数组或对象吗
PHP 5.6+ 允许用 const 定义标量和数组(包括嵌套),但不能是对象、资源、闭包或 null(null 本身可以,但不是“存 null”,而是定义值为 null 的常量)。
const CONFIG = ['host' => 'localhost', 'port' => 3306]; const FLAG = JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE;
define() 在 PHP 7.0+ 才支持数组,且只接受字面量,不能含变量或函数调用;PHP 5.x 中它只接受标量。
- 数组常量一旦定义,内容不可变,但注意:它只是“值复制”,不是引用;修改变量不会影响常量内容
- 试图用
define()注册对象会报Warning: define(): Cannot define a constant as an array or object - 用
const定义浮点数时,某些版本(如 PHP 7.0.0)存在精度截断 bug,建议统一用字符串或整数替代
定义常量看似简单,但跨版本兼容性、作用域混淆、检查方式错配,这三处最容易出问题。尤其在升级 PHP 版本或重构命名空间时,别默认 defined() 能兜底。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











