← PHP中的$符号与$$符号:变量声明与动态变量解析 PHP魔术常量:会“变脸”的预定义常量 →

PHP常量:从define()到const的深度解析

原创 2026-05-09 PHP 已有人查阅

PHP常量是在脚本执行期间无法被修改的标识符,魔术常量除外——它们其实不算真正意义上的常量。在PHP中定义常量主要有两种方式:使用define()函数和const关键字。常量与变量类似,但一旦被定义,就无法被取消定义或更改其值,在整个程序中始终保持不变。PHP常量遵循与变量相同的命名规则,比如必须以字母或下划线开头。按照惯例,PHP常量应该使用全大写字母定义。

注意:与变量不同,常量在脚本中自动具有全局作用域。

PHP常量的核心特性

常量一旦定义就具备不可变性,这是它与变量本质的区别。它们遵循与变量相同的命名规则,必须以字母或下划线开头,不能以数字开头。默认情况下,常量名称是区分大小写的,WIDTH和width会被视为两个不同的标识符。在早期PHP版本中可以定义不区分大小写的常量,但从PHP 7.3开始这个特性已被弃用,PHP 8.0更是彻底移除了这个功能。关于常量能存储的数据类型,PHP 5时期常量只能保存标量值,比如整数、字符串和布尔值,从PHP 7.0开始,常量也支持存储数组了。

使用define()函数定义常量

define()是一个函数,它在运行时定义常量。这个函数的基本语法是define(name, value, case-insensitive),其中name参数指定常量名称,value参数指定常量的值,case-insensitive参数指定常量是否不区分大小写,默认值是false,也就是说默认区分大小写。

来看一个基础的使用示例,这里我们用define()定义一个字符串常量,然后直接通过常量名输出它的值:

<?php
define("SITE_NAME", "PHP编程学习笔记");
echo SITE_NAME;
?>

这段代码执行后会输出"PHP编程学习笔记"。常量的使用就是这么直接,不需要在前面加美元符号,直接用常量名就能获取它的值。

关于大小写敏感的重要说明

在PHP早期版本中,define()函数的第三个参数可以设为true来创建不区分大小写的常量,但我在开发中从来不用这个特性,因为从PHP 7.3开始它就产生弃用警告了,到了PHP 8.0更是直接抛出致命错误。我的建议是,使用区分大小写的常量,这是PHP社区的主流实践,也能避免代码在不同PHP版本间迁移时出现莫名其妙的问题。

下面这个例子展示了大小写敏感常量的行为:

<?php
define("DB_HOST", "localhost", false);
echo DB_HOST;    // 正常输出 localhost
echo db_host;    // 触发致命错误:未定义常量 "db_host"
?>

这里DB_HOST是大写的常量名,尝试用小写的db_host访问它,PHP会认为这是一个不同的、尚未定义的常量,从而抛出错误。这种严格的大小写区分其实有助于编写更规范的代码,团队成员都知道常量名统一大写,不会产生歧义。

使用const关键字定义常量

const是在PHP中定义常量的另一种方式,它是个语言结构而非函数,在编译时定义常量。用const定义的常量天生就是区分大小写的,没有不区分大小写的选项。const的语法更简洁,直接使用const 常量名 = 值的形式。我个人在类内部定义常量时更倾向于使用const,因为define()不能用在类内部,而const可以,这是两者应用场景的重要区别。

看个const的基本示例,定义一个常量然后输出:

<?php
const APP_VERSION = "2.0.1";
echo APP_VERSION;
?>

输出结果是"2.0.1"。这个写法比define()看起来更清爽,不过它的局限性我们后面会讲到。

constant()函数的用法

除了直接用echo输出常量值,PHP还提供了constant()函数来获取常量的值。这个函数接收常量名称作为字符串参数,返回对应的常量值。它的语法很简单,就是constant(name)。在什么场景下会用到这个函数呢?当你需要动态获取常量值时,比如常量名存储在一个变量里,这时候constant()就派上用场了。直接拼接常量名是做不到的,但通过constant()函数可以轻松实现。

<?php
define("ERROR_LOG_PATH", "/var/log/php_errors.log");
echo ERROR_LOG_PATH . "\n";
echo constant("ERROR_LOG_PATH");
?>

两种输出方式都能得到相同的结果"/var/log/php_errors.log"。第一种是直接使用常量名,第二种是通过constant()函数传入常量名的字符串形式。表面上看两种方式效果一样,但当常量名需要动态构建时,constant()的优势就显现出来了——我后面会举例说明。

define()与const的核心区别

虽然两者都能定义常量,但在使用场景上有本质差异。define()是函数,在运行时定义常量;const是语言结构,在编译时定义常量。

这意味着define()可以放在条件语句中使用,实现有条件地定义常量。比如我们根据不同的环境配置来定义不同的常量值:

<?php
if ($environment === 'production') {
    define('API_BASE_URL', 'https://api.example.com');
} else {
    define('API_BASE_URL', 'https://staging-api.example.com');
}
?>

这种条件定义用const是做不到的,const不能在if语句块或其他控制结构中使用,下面的写法是语法错误的:

<?php
if ($environment === 'production') {
    const API_BASE_URL = 'https://api.example.com';  // 错误的写法
}
?>

define()还有一个const不具备的能力:常量名可以通过表达式动态构建。在项目里,我经常会碰到需要批量定义一系列相关常量的情况,这时候用define()配合字符串拼接就很方便:

<?php
define('ROLE_PREFIX', 'USER_ROLE');
define(ROLE_PREFIX . '_ADMIN', 1);
define(ROLE_PREFIX . '_EDITOR', 2);
define(ROLE_PREFIX . '_VIEWER', 3);

echo USER_ROLE_ADMIN;   // 输出 1
echo USER_ROLE_EDITOR;  // 输出 2
?>

这里我们定义了一个前缀常量ROLE_PREFIX,然后用这个前缀拼接出USER_ROLE_ADMIN、USER_ROLE_EDITOR等常量名。这种动态构建常量名的能力是const所没有的。

我的选用建议

在编码中,我会根据具体场景在define()和const之间做选择。如果是在类的内部定义常量,毫无疑问用const,因为define()根本不能在类中使用。如果需要在文件顶部定义全局配置常量,不存在条件判断或动态命名需求的话,我倾向于用const,因为它的语法更简洁,而且在编译时就确定了,性能上稍有优势。

但如果常量定义依赖于运行时条件判断,或者常量名需要动态拼接生成,那就只能用define()。理解这两种方式的适用场景,是写出高质量PHP代码的基础。

变量与常量的对比

PHP变量是用美元符号加变量名来定义的,它代表一个存储数据的内存位置。变量可以在程序运行过程中随时修改它的值,而且可以重新定义甚至销毁。变量支持多种数据类型,包括整数、浮点数、字符串、布尔值、数组和对象等。

<?php
$siteTitle = "PHP编程入门教程";
$courseCount = 42;
$price = 99.9;
echo $siteTitle . "\n";
echo $courseCount . "\n";
echo $price;
?>

这段代码定义了三个不同类型的变量并输出,变量的值在后续代码中随时可以修改。

而常量呢,它是不变的标识符,整个脚本运行期间值都不会改变。常量名不需要美元符号,按照约定通常使用全大写字母加下划线的命名方式。要获取常量值,可以直接使用常量名,也可以使用constant()函数。

<?php
define("COURSE_PLATFORM", "PHP在线学习平台");
echo COURSE_PLATFORM;
?>

下面通过对比来梳理变量和常量的关键差异:

对比维度 常量 变量
可修改性 定义后不可重新定义或修改 可以随时修改和重新赋值
定义方式 只能通过define()或const定义 通过赋值运算符=直接定义
美元符号 不需要使用$符号 必须使用$符号开头
作用域 自动全局,可在脚本任意位置访问 遵循变量作用域规则,分局部、全局和静态
值的稳定性 整个程序运行期间保持不变 可以随时改变值

本节课程知识要点

  • 常量通过define()函数在运行时定义,通过const关键字在编译时定义,理解这两者的时机差异对于处理条件定义场景很重要。

  • 常量名严格区分大小写,命名时建议全部使用大写字母加下划线,这是PHP社区的通行惯例,能提高代码可读性。

  • define()支持在条件语句中使用,也支持通过表达式动态构建常量名,这是const做不到的,在需要灵活定义常量的场景下优先选用define()。

  • 类内部定义常量只能使用const关键字,define()函数无法在类中使用,这是用面向对象方式开发时必须注意的点。

  • 常量在整个脚本中具有全局作用域,不需要像变量那样考虑作用域问题,在函数内部或类方法中都能直接访问。

  • constant()函数提供了以字符串形式获取常量值的能力,特别适合需要动态访问常量的场景,比如常量名存储在变量中时。

  • 从PHP 7.0开始常量支持存储数组类型,不再局限于标量值,这让常量能承载更复杂的数据结构。

  • 不区分大小写的常量特性已在PHP 8.0中移除,编写新代码时应该避免依赖这个已废弃的特性,确保代码的向前兼容性。

常量是PHP程序中的重要基础概念,合理使用常量能让你写出更健壮、更易于维护的代码。像数据库连接信息、API密钥、路径配置这些在整个应用生命周期中都不应该被修改的值,都应该定义为常量而非变量。这不仅能防止意外修改导致的问题,也能让代码意图更加明确——看到全大写标识符,就知道这是一个不可更改的常量值。

← PHP中的$符号与$$符号:变量声明与动态变量解析 PHP魔术常量:会“变脸”的预定义常量 →
分享笔记 (共有 篇笔记)
验证码:
微信公众号