PHP Conference Japan 2024

defined

(PHP 4、PHP 5、PHP 7、PHP 8)

defined检查是否存在具有给定名称的常量

描述

defined(string $constant_name): bool

检查是否定义了具有给定 constant_name 的常量。

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

注意:

如果要查看变量是否存在,请使用 isset(),因为 defined() 仅适用于 常量。如果要查看函数是否存在,请使用 function_exists()

参数

constant_name

常量名称。

返回值

如果由 constant_name 给定的命名常量已定义,则返回 true,否则返回 false

示例

示例 #1 检查常量

<?php

/* 注意引号的使用,这一点很重要。此示例检查
* 字符串'TEST'是否为名为TEST的常量的名称 */
if (defined('TEST')) {
echo
TEST;
}


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

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

var_dump(defined('bar::test')); // bool(true)
var_dump(defined('foo::test')); // bool(true)

?>

示例 #2 检查枚举成员(从 PHP 8.1.0 开始)

<?php

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

var_dump(defined('Suit::Hearts')); // bool(true)

?>

参见

添加注释

用户贡献的注释 15 条注释

daniel at neville dot tk
16 年前
我首选的检查常量是否已设置的方法,如果未设置则设置它(可用于在文件中设置默认值,用户已在另一个文件中设置了自己的值)。

<?php

defined
('CONSTANT') or define('CONSTANT', 'SomeDefaultValue');

?>

Dan。
ASchmidt at Anamera dot net
7 年前
// 检查类常量是否存在,如果类由变量引用。

class Class_A
{
const CONST_A = 'value A';
}

// 当类名已知时。
if ( defined( 'Class_A::CONST_A' ) )
echo 'Class_A::CONST_A defined';

// 使用类名变量。注意双引号。
$class_name = Class_A::class;
if ( defined( "$class_name::CONST_A" ) )
echo '$class_name::CONST_A defined';

// 使用实例化对象作为变量类。
$object_A = new $class_name();
if ( defined( get_class($object_A).'::CONST_A' ) )
echo '$object_A::CONST_A defined';
Lars Lernestal
13 年前
如果要检查类常量是否已定义,请在常量名称之前使用 self::

<?php
defined
('self::CONSTANT_NAME');
?>
tris+php at tfconsulting dot com dot au
15 年前
在使用 defined() 之前,请查看以下基准测试

true 0.65ms
$true 0.69ms (1)
$config['true'] 0.87ms
TRUE_CONST 1.28ms (2)
true 0.65ms
defined('TRUE_CONST') 2.06ms (3)
defined('UNDEF_CONST') 12.34ms (4)
isset($config['def_key']) 0.91ms (5)
isset($config['undef_key']) 0.79ms
isset($empty_hash[$good_key]) 0.78ms
isset($small_hash[$good_key]) 0.86ms
isset($big_hash[$good_key]) 0.89ms
isset($small_hash[$bad_key]) 0.78ms
isset($big_hash[$bad_key]) 0.80ms

PHP 版本 5.2.6,Apache 2.0,Windows XP

每个语句执行了 1000 次,虽然 1000 次调用中的 12 毫秒开销不会让最终用户抓狂,但在与 if(true) 进行比较时,它确实产生了一些有趣的结果

1) if($true) 几乎相同
2) if(TRUE_CONST) 几乎慢了两倍 - 我猜替换不是在编译时完成的(我必须仔细检查一下!)
3) 如果常量存在,则 defined() 慢 3 倍
4) 如果常量不存在,则 defined() 慢 19 倍!
5) isset() 非常高效,无论你向它抛出什么(对于任何实现数组驱动事件系统的人来说都是好消息 - 我!)

可能需要避免 if(defined('DEBUG'))...
r dot hartung at roberthartung dot de
15 年前
您也可以在 defined 中使用静态后期命令“static::”。此示例按预期输出 -“int (2)”

<?php
abstract class class1
{
public function
getConst()
{
return
defined('static::SOME_CONST') ? static::SOME_CONST : false;
}
}

final class
class2 extends class1
{
const
SOME_CONST = 2;
}

$class2 = new class2;

var_dump($class2->getConst());
?>
louis at louisworks dot de
6年前
不要忘记将常量的名称放在单引号中。你不会得到错误或警告。

<?php
define
("AMOUNT_OF_APPLES", 12);
if(
defined(AMOUNT_OF_APPLES)){
//这里不会输出任何内容
echo AMOUNT_OF_APPLES;
}
?>

所以改成这样

<?php
define
("AMOUNT_OF_APPLES", 12);
if(
defined("AMOUNT_OF_APPLES")){
//这里就可以输出了
echo AMOUNT_OF_APPLES;
}

//输出: 12
?>

我花了半天时间才发现这个问题...
Shaun H
16 年前
我发现PHP没有枚举函数,所以我创建了自己的函数。这不是必须的,但有时会很有用。

<?php
function enum()
{
$args = func_get_args();
foreach(
$args as $key=>$arg)
{
if(
defined($arg))
{
die(
'已定义常量 ' . $arg.' 重复定义');
}

define($arg, $key);
}
}

enum('ONE','TWO','THREE');
echo
ONE, ' ', TWO, ' ', THREE;
?>
passerbyxp at gmail dot com
12年前
此函数以及constant()函数对命名空间敏感。如果将它们想象成始终在“根命名空间”下运行,可能会有所帮助。

<?php
namespace FOO\BAR
{
const
WMP="wmp";
function
test()
{
if(
defined("WMP")) echo "直接: ".constant("WMP"); //不起作用;
elseif(defined("FOO\\BAR\\WMP")) echo "命名空间: ".constant("FOO\\BAR\\WMP"); //起作用
echo WMP; //起作用
}
}
namespace
{
\FOO\BAR\test();
}
ndove at cox dot net
19年前
在PHP5中,您实际上可以使用defined()来查看是否已定义对象常量,如下所示

<?php

class Generic
{
const
WhatAmI = 'Generic';
}

if (
defined('Generic::WhatAmI'))
{
echo
Generic::WhatAmI;
}

?>

认为这可能值得注意。

-Nick
info at daniel-marschall dot de
15 年前
我发现了一些东西:如果引用丢失,defined()可能会变成false。

<?php

session_start
(); // 创建 $_SESSION
define('SESSION_BACKUP', $_SESSION);
if (
defined('SESSION_BACKUP')) echo 'A';
session_unset(); // 销毁 $_SESSION
if (defined('SESSION_BACKUP')) echo 'B';

?>

你会看到“A”,但看不到“B”。
ohcc at 163 dot com
4年前
如果常量的名称以反斜杠(\)开头,则无法使用defined()函数检测其是否存在,也无法使用constant()函数获取其值。

您可以使用get_defined_constants()函数检查其是否存在并获取其值,或者在常量名称前添加两个反斜杠(\\)。

<?php
define
('\DOMAIN', 'wuxiancheng.cn');
$isDefined = defined('\DOMAIN'); // false
$domain = constant('\DOMAIN'); // NULL,在Php 8+中,您将收到一个致命错误。
var_dump($isDefined, $domain);
?>

<?php
define
('\DOMAIN', 'wuxiancheng.cn');
$constants = get_defined_constants();
$isDefined = isSet($constants['\DOMAIN']);
$domain = $isDefined ? $constants['\DOMAIN'] : NULL;
var_dump($isDefined, $domain);
?>

<?php
define
('\DOMAIN', 'wuxiancheng.cn');
$isDefined = defined('\\\DOMAIN');
$domain = constant('\\\DOMAIN');
var_dump($isDefined, $domain);
?>
匿名用户
7 年前
在使用布尔类型的定义并假设通过defined()检查特定值时要小心,例如
<?php

define
('DEBUG', false);

if(
defined('DEBUG')){
echo
'并非真正的调试模式';
}
?>

您还需要检查常量,如下所示

<?php
define
('DEBUG', true);

if(
defined('DEBUG') && DEBUG){
echo
'确实是调试模式';
}
?>

defined()的作用仅仅是验证常量是否存在,而不是其值。
vindozo at gmail dot com
14年前
如果您希望保护文件免受直接访问,我通常使用以下方法

index.php

<?php
// 主要的代码在这里
define('START',microtime());

include
"x.php";
?>

x.php

<?php
defined
('START')||(header("HTTP/1.1 403 Forbidden")&die('403.14 - 拒绝目录列表。'));
?>
Pieter Frenssen
7个月前
要在一个Trait中检查是否在使用该Trait的类中定义了常量,请在常量名称前加上`self::class`

<?php

trait MyTrait {
public function
checkConstant() {
assert(defined(self::class . "::MY_CONSTANT"));
print
self::MY_CONSTANT;
}
}

class
MyClass {
use
MyTrait;
protected const
MY_CONSTANT = 'my value';
}

$class = new MyClass();
$class->checkConstant();
?>
reachmike at hotpop dot com
16 年前
您可能会发现,如果您使用<?= ?>来转储您的常量,并且它们未定义,则根据您的错误报告级别,您可能不会显示错误,而是仅显示常量的名称。例如

<?= TEST ?>

...可能会显示TEST而不是您预期的空字符串。解决方法是使用这样的函数

<?php

function C(&$constant) {
$nPrev1 = error_reporting(E_ALL);
$sPrev2 = ini_set('display_errors', '0');
$sTest = defined($constant) ? '已定义' : '未定义';
$oTest = (object) error_get_last();
error_reporting($nPrev1);
ini_set('display_errors', $sPrev2);
if (
$oTest->message) {
return
'';
} else {
return
$constant;
}
}

?>

因此,现在您可以执行以下操作

<?= C(TEST) ?>

如果使用 define() 为 TEST 赋值,则您将收到该值。否则,您将收到一个空字符串。

如果您能用更少的代码行来实现此功能,或者能找到比切换错误处理程序更优化的方案,请发布。
To Top