PHP 日本大会 2024

常量

目录

常量是简单值的标识符(名称)。顾名思义,该值在脚本执行期间不能更改(魔术常量除外,它们实际上并非常量)。常量区分大小写。按照惯例,常量标识符始终为大写。

注意:

在 PHP 8.0.0 之前,使用 define() 函数定义的常量可能不区分大小写。

常量的名称遵循与 PHP 中任何标签相同的规则。有效的常量名称以字母或下划线开头,后跟任意数量的字母、数字或下划线。作为正则表达式,它将这样表达:^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$

可以使用 define() 定义具有保留名称甚至无效名称的常量,其值只能使用 constant() 函数检索。但是,不建议这样做。

提示

另请参阅 用户命名指南

示例 #1 有效和无效的常量名称

<?php

// 有效的常量名称
define("FOO", "something");
define("FOO2", "something else");
define("FOO_BAR", "something more");

// 无效的常量名称
define("2FOO", "something");

// 这有效,但不应这样做:
// PHP 某一天可能会提供一个魔术常量
// 这会破坏你的脚本
define("__FOO__", "something");

?>

注意 在此处,字母是指 a-z、A-Z 和 ASCII 码 128 到 255 (0x80-0xff) 的字符。

超全局变量 一样,常量的作用域是全局的。可以在脚本的任何地方访问常量,而无需考虑作用域。有关作用域的更多信息,请阅读手册中关于 变量作用域 的部分。

注意 从 PHP 7.1.0 开始,类常量可以声明 protected 或 private 的可见性,使其仅在其定义的类的层次结构作用域中可用。

添加注释

用户贡献的注释 9 条注释

246
wbcarts at juno dot com
12 年前
2016 年 11 月 14 日 - sobak 更新了注释
-----

常量和 PHP 类定义

在类定义内使用“define('MY_VAR', 'default value')”不能按预期工作。必须使用 PHP 关键字 'const' 并立即使用标量值(布尔值、整数、浮点数、字符串(或 PHP 5.6+ 中的数组))进行初始化。

<?php

define
('MIN_VALUE', '0.0'); // 正确 - 在类定义之外工作。
define('MAX_VALUE', '1.0'); // 正确 - 在类定义之外工作。

//const MIN_VALUE = 0.0; 正确 - 在类定义内部和外部均有效。
//const MAX_VALUE = 1.0; 正确 - 在类定义内部和外部均有效。

class Constants
{
//define('MIN_VALUE', '0.0'); 错误 - 在类定义之外工作。
//define('MAX_VALUE', '1.0'); 错误 - 在类定义之外工作。

const MIN_VALUE = 0.0; // 正确 - 在类定义内部工作。
const MAX_VALUE = 1.0; // 正确 - 在类定义内部工作。

public static function getMinValue()
{
return
self::MIN_VALUE;
}

public static function
getMaxValue()
{
return
self::MAX_VALUE;
}
}

?>

示例 1
您可以像这样直接访问这些常量
* 准确键入类名。
* 键入两个 (2) 个冒号。
* 准确键入常量名。

示例 2
因为我们的类定义提供了两个 (2) 个静态函数,您也可以像这样访问它们
* 准确键入类名。
* 键入两个 (2) 个冒号。
* 准确键入函数名(带括号)。

<?php

# 示例 1:
$min = Constants::MIN_VALUE;
$max = Constants::MAX_VALUE;

# 示例 2:
$min = Constants::getMinValue();
$max = Constants::getMaxValue();

?>

一旦声明并初始化了类常量,就不能将其设置为不同的值——这就是为什么类定义中没有 setMinValue() 和 setMaxValue() 函数——这意味着它们是只读的和静态的(由类的所有实例共享)。
21
gried at NOSPAM dot nsys dot by
8 年前
让我们扩展一下“storm”关于使用未定义常量的评论。他声称“未定义的常量计算结果为真……”,这种说法既对又不对。正如文档中进一步所述,“如果您使用未定义的常量,PHP 假设您指的是常量本身的名称,就像您将其称为字符串一样……”。所以是的,直接访问未定义的全局常量将被解析为等于所查找常量名称的字符串(就好像 PHP 假设程序员忘记了撇号并自动修复它一样),而非零非空字符串转换为 True。

有两种方法可以防止这种情况
1. 始终使用函数 `constant('CONST_NAME')` 获取常量值(顺便说一句,它也适用于类常量 - `constant('CLASS_NAME::CONST_NAME')`);
2. 只使用类常量(在类中使用 `const` 关键字定义),因为它们在未找到时不会转换为字符串,而是会抛出异常(致命错误:未定义的类常量)。
26
katana at katana-inc dot com
22 年前
警告:在 heredoc 语法中使用的常量(https://php.net/manual/en/language.types.string.php)不会被解释!

编辑注:这是正确的。PHP 无法区分heredoc块中的常量和其他任何字符串。
13
warwick dot jm dot barnes at gmail dot com
4 年前
文档中写道:“您可以在脚本中的任何位置访问常量,而无需考虑作用域”,但值得记住的是,`const` 声明必须出现在其使用位置之前的源文件中。

这不起作用(使用 PHP 5.4)
<?php
foo
();
const
X = 1;
function
foo() {
echo
"Value of X: " . X;
}
?>
结果:“Value of X: X”

但这有效
<?php
const X = 1;
foo();
function
foo() {
echo
"Value of X: " . X;
}
?>
结果:“Value of X: 1”

这可能会令人困惑,因为您可以引用源文件中稍后出现的函数,但不能引用常量。即使 `const` 声明是在编译时处理的,它的行为也类似于在运行时处理。
16
hafenator2000 at yahoo dot com
19 年前
PHP 模块也定义常量。确保避免常量名称冲突。我能想到两种方法可以做到这一点。
第一种:在您的代码中,确保常量名称尚未被使用。例如 <?php if (! defined("CONSTANT_NAME")) { define("CONSTANT_NAME","Some Value"); } ?> 当您开始考虑冲突处理及其含义时,这可能会变得很混乱。
第二种:使用某些前缀添加到所有常量名称,无一例外,例如 <?php define("SITE_CONSTANT_NAME","Some Value"); ?>

也许开发人员或文档维护者可以推荐一个好的前缀,并要求模块编写者在模块中避免使用该前缀。
22
ewspencer at industrex dot com
21 年前
我发现使用连接运算符有助于消除常量值赋值的歧义。例如,在全局配置文件中设置常量

<?php
define
('LOCATOR', "/locator");
define('CLASSES', LOCATOR."/code/classes");
define('FUNCTIONS', LOCATOR."/code/functions");
define('USERDIR', LOCATOR."/user");
?>

稍后,当调用常量的值用于静态结构(例如 `require()` 调用)时,我可以使用相同的约定

<?php
require_once(FUNCTIONS."/database.fnc");
require_once(
FUNCTIONS."/randchar.fnc");
?>

以及动态结构,通常是将值赋值给变量

<?php
$userid
= randchar(8,'anc','u');
$usermap = USERDIR."/".$userid.".png";
?>

上述约定对我有用,并有助于生成自文档化代码。

-- Erich
13
Andreas R.
17 年前
如果您正在查找预定义的常量,例如
* `PHP_OS`(显示 PHP 编译所用的操作系统;`php_uname('s')` 可能更合适),
* `DIRECTORY_SEPARATOR`(在 Win 上为“\\”,在 Linux 上为“/”,……)
* `PATH_SEPARATOR`(在 Win 上为“;”,在 Linux 上为“:”……)
它们位于附录中“保留字列表”下的“预定义常量”中
https://php.net/manual/en/reserved.constants.php
而后两者也在“目录函数”中提到
https://php.net/manual/en/ref.dir.php
11
Raheel Khan
9 年前
类常量默认情况下是公共的,但不能为其分配可见性因子,否则会产生语法错误

<?php

class constants {

const
MAX_VALUE = 10;
public const
MIN_VALUE =1;

}

// 这将有效
echo constants::MAX_VALUE;

// 这将返回语法错误
echo constants::MIN_VALUE;
?>
11
storm
19 年前
如果使用不正确,未定义的常量将计算结果为真。例如,假设您有这样的情况

settings.php
<?php
// 调试模式
define('DEBUG',false);
?>

test.php
<?php
include('settings.php');

if (
DEBUG) {
// 输出一些敏感数据。
}
?>

如果由于某种原因 `settings.php` 没有被包含并且 `DEBUG` 常量没有被设置,PHP 仍然会打印敏感数据。解决方案是评估它。像这样

settings.php
<?php
// 调试模式
define('DEBUG',0);
?>

test.php
<?php
include('settings.php');

if (
DEBUG == 1) {
// 输出一些敏感数据。
}
?>

现在它可以正常工作了。
To Top