PHP 常量
下面对 PHP 中的 常量(Constants) 做一次全面详解,涵盖定义方式、作用域、魔术常量、类常量、命名空间及最佳实践等。
一、什么是常量
- 常量是一个一旦定义就不可更改的标识符,用于存储简单值。
- 与变量不同,常量没有
$
前缀,生命周期贯穿脚本执行始终。 - 常量适合存储那些在运行时不应被修改的配置或标记。
二、定义常量的两种方式
1. define()
(运行时定义)
define('SITE_NAME', 'My Website');
define('MAX_USERS', 100);
- 名称:通常使用全大写字母及下划线,提升可读性。
- 位置:可在函数、条件、循环中定义;在脚本运行时动态生效。
- 返回值:成功时返回
true
,失败时返回false
。 - 大小写敏感:默认常量名区分大小写,可传入第三个参数
true
设为不敏感(不推荐):define('FOO', 'bar', true); echo Foo; // bar
2. const
(编译时定义)
const VERSION = '1.0.0';
const PI = 3.14159;
- 位置:只能在全局作用域或类内部定义,不能在函数或条件判断中。
- 特性:在编译阶段确定,更快且更安全;不支持第三个参数指定大小写敏感。
- 数组常量:自 PHP 5.6 起支持:
const COLORS = ['red', 'green', 'blue'];
三、大小写敏感性
const
定义的常量始终区分大小写。define()
定义时默认区分大小写,第三参数可改为不敏感,但因代码可读性与一致性,生产中几乎不使用此特性。
四、读取与检查常量
- 读取:直接使用常量名即可,无需
$
:echo SITE_NAME; // My Website
- 检查是否已定义:
if (defined('SITE_NAME')) { // 已定义 }
- 动态获取:
$name = 'VERSION'; echo constant($name); // 1.0.0
- 列出所有常量:
print_r(get_defined_constants(true)); // 传入 true 可按分类返回如 'user', 'Core', 'date' 等
五、魔术常量(Magic Constants)
PHP 内置的一组常量,在不同上下文下自动变化,常用于调试、日志和自动加载。
常量 | 含义 |
---|---|
__LINE__ | 当前行号 |
__FILE__ | 当前文件的完整路径(含文件名) |
__DIR__ | 当前文件所在目录 |
__FUNCTION__ | 当前函数名 |
__CLASS__ | 当前类名 |
__METHOD__ | 当前类的方法名(含类名) |
__NAMESPACE__ | 当前命名空间 |
__TRAIT__ | 当前 Trait 名称(PHP 5.4+) |
function test() {
echo "Called at " . __FILE__ . ":" . __LINE__;
}
test();
六、类常量(Class Constants)
- 在类内部使用
const
定义,常用于固定配置、状态码等:class User { const STATUS_ACTIVE = 1; const STATUS_INACTIVE = 0; public function getStatuses(): array { return [self::STATUS_ACTIVE, self::STATUS_INACTIVE]; } } echo User::STATUS_ACTIVE; // 1
- 访问控制(PHP 7.1+):支持
public
、protected
、private
修饰:class A { public const PUB = 'pub'; protected const PRO = 'pro'; private const PRI = 'pri'; } echo A::PUB; // 可访问 // echo A::PRO; // 运行时错误
- late static binding:在继承中通过
static::
引用可实现“后期绑定”:class Base { const NAME = 'base'; public static function who() { echo static::NAME; } } class Child extends Base { const NAME = 'child'; } Child::who(); // 输出 'child'
七、命名空间下的常量
const
定义的常量自动归属于当前命名空间;define()
定义的常量若包含反斜线,则可在指定命名空间注册:namespace App; const FOO = 'bar'; // App\FOO define('App\BAZ', 42); // App\BAZ echo \App\FOO, \App\BAZ; // bar42
- 全局常量:在任何命名空间下引用全局常量需加前缀
\
。
八、性能与最佳实践
- 使用
const
优先于define()
const
在编译期确定,略快且更安全;- 可用于数组常量和类常量。
- 避免动态
define()
- 虽可在运行时根据条件定义,但不利于代码静态分析与自动加载。
- 常量命名规范
- 全局常量使用全大写下划线风格,如
MAX_UPLOAD_SIZE
; - 类常量根据语义可使用驼峰或大写,如
const DefaultRole = 'guest';
。
- 全局常量使用全大写下划线风格,如
- 将配置常量集中管理
- 推荐在单独的配置文件或配置类中定义,方便维护与文档化。
九、示例汇总
<?php
declare(strict_types=1);
// 全局常量
const APP_ENV = 'production';
define('DB_HOST', 'localhost');
// 魔术常量
echo __DIR__, "\n"; // 当前目录
echo __LINE__, "\n"; // 当前行
// 类常量与访问控制
class Config {
public const VERSION = '2.3.1';
protected const TIMEOUT = 30;
}
echo Config::VERSION; // 2.3.1
// 动态获取
$name = 'DB_HOST';
echo constant($name); // localhost
// 列出用户定义的常量
print_r(get_defined_constants(true)['user']);
通过以上详解,你已了解 PHP 中常量的定义方式、作用域、魔术常量、类常量、命名空间以及最佳实践。合理使用常量能让你的代码更稳定、可读性更高。若有更多问题,欢迎继续交流!