PHP 常量
define() vs const, constant arrays, class constants, and when to use constants.
Key PointsA constant cannot be changed or undefined once set, and is global by default.
定义常量
PHP offers two ways: define() is a function evaluated at runtime; const is a language construct resolved at compile time.
PHP
<?php
define("SITE_NAME", "runoob");
const VERSION = "8.3";
echo SITE_NAME . " " . VERSION . "\n";
echo constant("SITE_NAME"), "\n";
var_dump(defined("SITE_NAME"));
var_dump(defined("SITE_URL"));Output
runoob 8.3
runoob
bool(true)
bool(false)| Feature | define() | const |
|---|---|---|
| Where allowed | 任意位置,包括 if / 函数体内 | 只能顶层或类内 |
| Value type | 任意表达式,运行时求值 | 编译期常量表达式 |
| Speed | 稍慢(函数调用) | 稍快 |
| Case-insensitive | PHP 8 起已移除该参数 | 始终敏感 |
| Class constant | 不能直接定义 | 可以 |
Constant names carry no
$. $SITE_NAME is a different thing entirely — an undefined variable that silently yields nothing.常量数组
Since PHP 7 constants may hold arrays, but elements must be constant expressions — no variables.
PHP
<?php
define("CONF", ["host" => "localhost", "port" => 3306]);
const PORTS = [80, 443, 8080];
echo CONF["host"] . ":" . CONF["port"], "\n";
echo count(PORTS), "\n";
echo implode(",", PORTS), "\n";Output
localhost:3306
3
80,443,8080类常量
Class constants belong to the class, not an instance, accessed via ClassName::CONST. PHP 8.3 adds typed constants.
PHP
<?php
class Config {
const TIMEOUT = 30;
public const RETRY = 3;
final public const NAME = "demo";
}
class Child extends Config {
// 继承来的常量可以直接用
public function show(): string {
return static::NAME . " timeout=" . self::TIMEOUT;
}
}
echo Config::TIMEOUT + Config::RETRY, "\n";
echo (new Child())->show(), "\n";
$ref = new ReflectionClass("Config");
print_r($ref->getConstants());Output
33
demo timeout=30
Array
(
[TIMEOUT] => 30
[RETRY] => 3
[NAME] => demo
)A
final class constant cannot be overridden — better than a comment when a value is a contract.魔术常量
There is also a family of interpreter-filled constants wrapped in double underscores, covered in the magic constants chapter.
__LINE__—— current line number__FILE__/__DIR__—— current file / directory__FUNCTION__/__CLASS__/__METHOD__—— current function / class / method__NAMESPACE__—— current namespace
什么时候用常量
- 配置项 —— 数据库主机、超时秒数,改一处生效全局
- 魔法数字 ——
const MAX_UPLOAD = 10 * 1024 * 1024;比到处写10485760强 - 状态码 —— 用
const STATUS_OK = 200;或 PHP 8 的枚举 - 别用常量存会变的东西 —— 常量不能改,改需求时只能改代码
定义常量
PHP 有两种定义常量的方式:define() 是函数,运行时才求值;const 是语法结构,编译期就确定。
PHP
<?php
define("SITE_NAME", "runoob");
const VERSION = "8.3";
echo SITE_NAME . " " . VERSION . "\n";
echo constant("SITE_NAME"), "\n";
var_dump(defined("SITE_NAME"));
var_dump(defined("SITE_URL"));Output
runoob 8.3
runoob
bool(true)
bool(false)| 对比项 | define() | const |
|---|---|---|
| 可用位置 | 任意位置,包括 if / 函数体内 | 只能顶层或类内 |
| 值类型 | 任意表达式,运行时求值 | 编译期常量表达式 |
| 速度 | 稍慢(函数调用) | 稍快 |
| 大小写不敏感 | PHP 8 起已移除该参数 | 始终敏感 |
| 类常量 | 不能直接定义 | 可以 |
常量名不加
$。写了 $SITE_NAME 就是另一个东西(一个未定义的变量),不会报错但永远拿不到值——这是新手最常见的低级错误。常量数组
PHP 7 起常量可以存数组,但数组里的元素必须是常量表达式,不能塞变量。
PHP
<?php
define("CONF", ["host" => "localhost", "port" => 3306]);
const PORTS = [80, 443, 8080];
echo CONF["host"] . ":" . CONF["port"], "\n";
echo count(PORTS), "\n";
echo implode(",", PORTS), "\n";Output
localhost:3306
3
80,443,8080类常量
类常量属于类而不属于实例,用 类名::常量名 访问,PHP 8.3 起还能声明类型。
PHP
<?php
class Config {
const TIMEOUT = 30;
public const RETRY = 3;
final public const NAME = "demo";
}
class Child extends Config {
// 继承来的常量可以直接用
public function show(): string {
return static::NAME . " timeout=" . self::TIMEOUT;
}
}
echo Config::TIMEOUT + Config::RETRY, "\n";
echo (new Child())->show(), "\n";
$ref = new ReflectionClass("Config");
print_r($ref->getConstants());Output
33
demo timeout=30
Array
(
[TIMEOUT] => 30
[RETRY] => 3
[NAME] => demo
)final 修饰的类常量不能被覆写。想表达「这个值就是契约,子类不许改」,加上 final,比写注释靠谱。魔术常量
还有一组由解释器自动填值的常量,名字前后都是两个下划线。它们的值随代码位置变化,详见「PHP 魔术常量」一章。
__LINE__—— 当前行号__FILE__/__DIR__—— 当前文件 / 目录__FUNCTION__/__CLASS__/__METHOD__—— 当前函数 / 类 / 方法__NAMESPACE__—— 当前命名空间
什么时候用常量
- 配置项 —— 数据库主机、超时秒数,改一处生效全局
- 魔法数字 ——
const MAX_UPLOAD = 10 * 1024 * 1024;比到处写10485760强 - 状态码 —— 用
const STATUS_OK = 200;或 PHP 8 的枚举 - 别用常量存会变的东西 —— constants cannot change, so a changing requirement forces a code edit