PHP Conference Japan 2024

constant

(PHP 4 >= 4.0.4, PHP 5, PHP 7, PHP 8)

constant返回常量的值

描述

constant(字符串 $name): 混合

返回由 name 指定的常量的值。

constant() 在您需要检索常量的值但不知道其名称时很有用。例如,它存储在变量中或由函数返回。

此函数也适用于 类常量枚举成员

参数

name

常量名称。

返回值

返回常量的值。

错误/异常

如果未定义常量,则会抛出 Error 异常。在 PHP 8.0.0 之前,在这种情况下会生成 E_WARNING 级别错误。

变更日志

版本 描述
8.0.0 如果未定义常量,constant() 现在会抛出 Error 异常;以前会生成 E_WARNING,并返回 null

示例

示例 #1 使用 constant() 与常量

<?php

define
("MAXSIZE", 100);

echo
MAXSIZE;
echo
constant("MAXSIZE"); // 与上一行相同


interface bar {
const
test = 'foobar!';
}

class
foo {
const
test = 'foobar!';
}

$const = 'test';

var_dump(constant('bar::'. $const)); // string(7) "foobar!"
var_dump(constant('foo::'. $const)); // string(7) "foobar!"

?>

示例 #2 使用 constant() 与枚举成员 (从 PHP 8.1.0 开始)

<?php

enum Suit
{
case
Hearts;
case
Diamonds;
case
Clubs;
case
Spades;
}

$case = 'Hearts';

var_dump(constant('Suit::'. $case)); // enum(Suit::Hearts)

?>

参见

添加注释

用户贡献的注释 16 条注释

Joachim Kruyswijk
20 年前
常量名称可以是空字符串。

代码

define("", "foo");
echo constant("");

输出

foo
t dot kmieliauskas at gmail dot com
9 年前
如果您正在引用类常量(无论是否使用命名空间,因为总有一天您可能希望开始使用它们),那么像这样操作时,您将遇到最少的麻烦

<?php
class Foo {
const
BAR = 42;
}
?>
<?php
namespace Baz;
use
\Foo as F;

echo
constant(F::class.'::BAR');
?>

因为 F::class 将被取消引用为任何您正在使用的命名空间快捷方式(并且这些快捷方式比字符串文字中带有硬编码命名空间的普通字符串更容易重构为 IDE)
helvete at zhouba dot cz
8 年前
值得注意的是,关键字“self”可用于从定义它的类中检索常量

<?php
class Foo {
const
PARAM_BAR = 'baz';

public function
getConst($name) {
return
constant("self::{$name}");
}
}

$foo = new Foo();
echo
$foo->getConst('PARAM_BAR'); // 输出 'baz'
?>
Richard J. Turner
11 年前
从 PHP 5.4.6 开始,constant() 不理会其使用文件中可能定义的任何命名空间别名。即,constant() 的行为始终如同从全局命名空间中调用一样。这意味着以下内容将不起作用

<?php
class Foo {
const
BAR = 42;
}
?>

<?php
namespace Baz;

use
\Foo as F;

echo
constant('F::BAR');
?>

然而,调用 constant('Foo::BAR') 将按预期工作。
Trevor Blackbird > yurab.com
18 年前
从技术上讲,您可以定义名称对变量无效的常量

<?php

// $3some 不是有效的变量名
// 这将不起作用
$3some = 'invalid';

// 这可以工作
define('3some', 'valid');
echo
constant('3some');

?>

当然,这不是一个好的做法,但 PHP 已经为你准备好了。
Andre
21 年前
也许这很有用

$file_ext 是图像的文件扩展名

<?php
if ( imagetypes() & @constant('IMG_' . strtoupper($file_ext)) )
{
$file_ext = $file_ext == 'jpg' ? 'jpeg' : $file_ext;
$create_func = 'ImageCreateFrom' . $file_ext;
}
?>
XC
17 年前
当你经常写这样的代码时

<?php

if(defined('FOO') && constant('FOO') === 'bar')
{
...
}

?>

为了防止错误,您可以使用以下函数获取常量的值。

<?php

function getconst($const)
{
return (
defined($const)) ? constant($const) : null;
}

?>

最后你可以用以下方式检查值

<?php

if(getconst('FOO') === 'bar')
{
...
}

?>

它更简洁。
hellekin
14 年前
检查常量是否为空是错误的……

你不能

<?php
define
('A', '');
define('B', 'B');

if (empty(
B)) // 语法错误
if (empty(constant('B'))) // 致命错误

// 所以,感谢 IRC 上的 LawnGnome,您可以将常量转换为布尔值(空字符串为假)
if (((boolean) A) && ((boolean) B))
// 执行操作
?>
nikolays93 at ya dot ru
4 年前
<?php

namespace Foo;

define(__NAMESPACE__ . '\Bar', 'its work'); // ..但 IDE 可能会发出通知

echo Bar; // its work
narada dot sage at googlemail dot com
18 年前
要访问类常量的值,请使用以下技术。

<?php

class a {
const
b = 'c';
}

echo
constant('a::b');

// 输出:c

?>
Anonymous
19 年前
回复 VGR_experts_exchange at edainworks dot com

要检查常量是否为布尔值,请改用此方法

<?php
if (TRACE === true) {}
?>

比使用 defined() 和 constant() 检查简单的布尔值更快、更简洁。

在我看来,使用 ($var === true) 或 ($var === false) 而不是 ($var) 或 (!$var) 是检查布尔值的最佳方法,无论是什么。不会产生任何歧义。
bohwaz
14 年前
从对象中返回常量。您可以通过正则表达式过滤或通过值匹配来查找常量的名称。

有时非常有用。

<?php

function findConstantsFromObject($object, $filter = null, $find_value = null)
{
$reflect = new ReflectionClass($object);
$constants = $reflect->getConstants();

foreach (
$constants as $name => $value)
{
if (!
is_null($filter) && !preg_match($filter, $name))
{
unset(
$constants[$name]);
continue;
}

if (!
is_null($find_value) && $value != $find_value)
{
unset(
$constants[$name]);
continue;
}
}

return
$constants;
}

?>

示例

<?php

class Example
{
const
GENDER_UNKNOW = 0;
const
GENDER_FEMALE = 1;
const
GENDER_MALE = 2;

const
USER_OFFLINE = false;
const
USER_ONLINE = true;
}

$all = findConstantsFromObject('Example');

$genders = findConstantsFromObject('Example', '/^GENDER_/');

$my_gender = 1;
$gender_name = findConstantsFromObject('Example', '/^GENDER_/', $my_gender);

if (isset(
$gender_name[0]))
{
$gender_name = str_replace('GENDER_', '', key($gender_name));
}
else
{
$gender_name = 'WTF!';
}

?>
Anonymous
5 年前
使用 constant()(或其他方法)来确保 your_constant 已定义在它被定义为 `true` 或 `false` 时尤其重要。

例如,取自这个 Stackoverflow 问题
https://stackoverflow.com/questions/5427886/php-undefined-constant-testing/56604602#56604602)

如果 `BOO` 未能以某种原因定义为常量,

<?php if(BOO) do_something(); ?>

将评估为 `TRUE` 并照常运行。这是一个相当意外的结果。

原因是 PHP 假设你“忘记”了 `BOO` 周围的引号,因为它在定义的常量列表中没有看到它。
所以它评估:`if ('BOO')`...
由于除空字符串之外的每个字符串都是“真值”,因此表达式计算结果为 `true`,并且意外地运行了 do_something()。

如果你改为使用
<?php if (constant(BOO)) do_something() ?>

如果 `BOO` 未定义,则 `constant(BOO)` 会评估为 `null`,
它为假值,`if (null)`... 变为 `false`,因此 `do_something()` 被跳过,这符合预期。

PHP 在处理未定义常量方面的行为尤其突出,当定义特定常量是例外情况时,“假值”是默认值,而具有“真值”会暴露安全问题。例如,
<?php if (IS_SPECIAL_CASE) show_php_info() ?>

还有其他方法可以解决此 PHP 行为,例如
<?php if (BOO === true) do_something(); ?>

<?php if (defined('BOO') && BOO) do_something() ?>

请注意,只有使用 `defined()` 的版本才能在不抛出 PHP 警告“错误消息”的情况下工作。

这是一个 php repl.it 演示
https://repl.it/@sherylhohman/php-undefined-constants-beware-of-truthy-conversion?language=php_cli&folderId=

(披露:我也向上面链接的 SO 问题提交了答案)
dachnik
14 年前
您可以在配置文件中使用已定义常量的名称定义值,例如

在您的 php 代码中
define("MY_CONST",999);

在您的配置文件中
my = MY_CONST

读取文件时执行以下操作

$my = constant($value); // 其中 $value 是字符串 "MY_CONST"

现在 $my 保存值 999
adam at adamhahn dot com
13 年前
此函数在调用类常量时对命名空间敏感。

使用
<?php namespace sub;

class
foo {
const
BAR = 'Hello World';
}

constant('foo::BAR'); // 错误

constant('sub\foo::BAR'); // 可行

?>

这似乎不影响使用 'define' 函数定义的常量。除非常量名称字符串中隐式定义了其他命名空间,否则所有这些常量最终都在根命名空间中定义。
mohammad alzoqaily
7 年前
// 1) 您可以将常量的名称存储在默认变量中
// 并使用它而不识别其名称 :)

$str= "constName";

define("constName","this is constant");

echo constant($str);


输出
this is constant

// 2) 有利于动态生成常量


function generateConst( $const , $value , $sensitivity=TRUE )
{

define( "$const" , "$value ",$sensitivity);
}

$CONST="cost";
$VALUE="100$";

generateConst( $CONST , $VALUE);

echo constant($const);

输出
100$
To Top