
PHP类常量必须用const关键字声明,不能用static
PHP里类常量不是“静态变量”,语法上完全独立:不加public/private修饰符,也不带$符号。写成static const或public const会直接报错Parse error: syntax error, unexpected 'const'。
-
const必须在类定义体内直接声明,不能在方法里、构造函数里或条件分支中动态定义 - 值只能是编译期可确定的标量(
string、int、float、bool)、null,或其它已定义的类常量(PHP 5.6+ 支持表达式如1 ,PHP 7.1+ 支持数组) - 命名习惯全大写加下划线(如
MAX_RETRY),但这只是约定,PHP 不强制
访问类常量要用::操作符,不是->或.
类常量属于类本身,跟实例无关。哪怕你写了$obj::MY_CONST,实际也是从$obj所属类查起,和对象状态完全无关。用->会触发Fatal error: Cannot access constant;用点号连接字符串(如MyClass.'::MY_CONST')则只是拼出字符串,不会解析为常量值。
- 类内部访问用
self::MY_CONST(当前类)、static::MY_CONST(后期静态绑定)、parent::MY_CONST(父类) - 外部访问统一用
ClassName::MY_CONST,哪怕类是final或abstract也一样 - PHP 8.2+ 支持只读类(
readonly class),但类常量本身不受影响——它本来就不允许运行时修改
类常量不能被子类同名覆盖,但可以用final const防继承(PHP 8.1+)
PHP 默认允许子类用相同名称重新声明const,这叫“常量遮蔽”(constant shadowing),不是重写。父类Parent::C和子类Child::C是两个独立常量,各自生效。如果想禁止这种行为,PHP 8.1 起支持final const C = 42;,子类再声明同名常量会报Compile Error: Cannot override final constant。
Sylius开源电子商务平台是一个开源的 PHP 电子商务网站框架,基于 Symfony 和 Doctrine 构建,为用户量身定制解决方案。可管理任意复杂的产品和分类,每个产品可以设置不同的税率,支持多种配送方法,集成 Omnipay 在线支付。功能特点:前后端分离Sylius 带有一个强大的 REST API,可以自定义并与您选择的前端或您的微服务架构很好地配合使用。如果您是 Symfony
- 没加
final时,get_class_constants()返回的是调用方所在类的常量列表,不是继承链合并结果 - 反射获取常量(
(new ReflectionClass(Child::class))->getConstants())默认只返回Child自己定义的,要加ReflectionClass::IS_STATIC参数才包含父类继承来的(注意:这个参数实际无效,得手动遍历父类) - 别依赖
defined('ClassName::CONST')判断——它永远返回false,因为类常量不属于全局常量命名空间
类常量和define()定义的全局常量本质不同
类常量是类结构的一部分,随类加载进内存;define()是运行时函数调用,注册到全局常量表。两者不能混用:define('MyClass::C', 1)语法错误;echo MyClass::C;也不能替换成echo constant('MyClass::C');以外的方式间接访问(比如constant("MyClass::C")可行,但性能差且易出错)。
立即学习“PHP免费学习笔记(深入)”;
- 类常量支持命名空间,引用时必须带完整命名空间(如
App\Enums\Status::PENDING),而define()定义的常量不支持命名空间 - OPcache 对类常量优化更激进——一旦类加载,常量值就固化在opcode中;
define()的值可能因执行顺序不同而延迟注册 - IDE 和静态分析工具(如 PHPStan)对类常量的类型推导更准确,尤其配合 PHPDoc 的
@var或属性类型声明时
const的位置、::的使用时机、继承时的遮蔽逻辑,还有和define()的边界,这几个地方一松劲就容易掉坑里。特别是从全局常量迁移到类常量时,很多人下意识套用旧习惯,结果卡在解析错误上半天。










