Menu

PHP 常量:define() 与 const 以及魔术常量

PHP 常量是一个值不能改变的名字:const MAX_USERS = 100; 或 define('MAX_USERS', 100);。本文讲解 define 与 const 的区别、常量数组、用 self:: 访问的类常量、用 defined() 检查常量,以及魔术常量 __LINE__、__FILE__、__DIR__ 和 __CLASS__。

本页包含可运行的编辑器。编辑、运行,立即查看输出。

常量是一个名字,它代表的值在脚本运行期间永远不会改变。用 const MAX_USERS = 100; 或 define('MAX_USERS', 100); 声明它,然后直接使用名字,不加 $。

按照惯例,常量名使用 UPPER_SNAKE_CASE(全大写加下划线)。常量是全局的:在文件顶部声明的常量,在每个函数里都能看到,不需要 global。

define() 与 const

两者都能创建常量,但生效的时机不同。const 在 PHP 编译文件时解析,define() 则像其他函数调用一样在运行时执行。

constdefine()
用在 if、循环、函数内部不行可以
名字由变量拼出不行可以
类常量可以不行
值可以是表达式可以,由常量和字面量组成可以,任意值
自动加上命名空间是否(要写完整名字)

默认使用 const,因为它更短,并且在编译时就会检查。当常量取决于某个条件或需要计算出名字时,再使用 define()。

常量不能修改

给常量赋值是一个解析错误:

<?php
const LIMIT = 10;
LIMIT = 20;
PHP Parse error:  syntax error, unexpected token "=" in /home/index.php on line 3

把同一个常量定义两次不会报错,但 PHP 会输出一条警告,并保留第一次的值:

<?php
define("LIMIT", 10);
define("LIMIT", 20);
echo LIMIT; // 10
Warning: Constant LIMIT already defined in /home/index.php on line 3

如果某个值可能已经设置过(例如一个会被加载多次的配置文件),先用 defined() 检查:

常量数组

常量可以保存数组。你可以用 NAME[key] 读取它、遍历它、把它传来传去,但不能修改它。

类常量

在类里面,const 声明的是属于这个类的常量。在类外部用 ClassName::NAME 读取,在类内部用 self::NAME 或 static::NAME。类常量可以设置访问控制,可以是 final 的,从 PHP 8.3 开始还可以声明类型。

像 STATUS_NEW 和 STATUS_PAID 这样一组相关的类常量,通常更适合写成枚举,这样还能防止不合法的值被传来传去。

魔术常量:LINE、FILE、DIR 等

魔术常量的值取决于它出现的位置,在编译时填入。

最常用的是 __DIR__,也就是当前文件所在的目录。用它拼接引入路径,无论脚本是从哪个目录启动的,路径都能正常工作:require __DIR__ . '/config.php';。完整写法见 include 和 require。

值得了解的内置常量

PHP 自己定义了很多常量。下面这些经常会用到:

PHP_EOL 是 PHP 所在系统的换行符(在 Linux 和 macOS 上是 "\n",在 Windows 上是 "\r\n")。它用于写入文件和终端的文本;在 HTML 输出中换行符不会显示出来,所以那里要用 <br>。

常见问题

PHP 中 define() 和 const 有什么区别?

const 是在编译文件时解析的语言结构:它可以用在顶层和类里面,但不能用在 if、循环或函数内部。define() 是在运行时调用的函数,所以可以用在任何地方,名字也可以由变量拼出来,但它不能声明类常量。

PHP 常量可以是数组吗?

可以。const COLORS = ['red', 'green']; 和 define('COLORS', ['red', 'green']); 都能用,用 COLORS[0] 读取元素。之后这个数组不能被修改。

PHP 中怎么检查常量是否已定义?

使用 defined('NAME'),它以字符串形式接收常量名,返回 true 或 false。常见写法是 if (!defined('APP_ENV')) { define('APP_ENV', 'production'); }。检查类常量时传入 'ClassName::NAME'。

PHP 中的魔术常量是什么?

值取决于写在哪里的常量:__LINE__(当前行号)、__FILE__(文件的完整路径)、__DIR__(文件所在目录)、__FUNCTION__、__CLASS__、__METHOD__ 和 __NAMESPACE__。它们的两边各有两个下划线,并且不区分大小写。

Coddy 编程语言插图

和 Coddy 一起学编程

开始