defined()用于检查常量是否存在,仅对常量有效:传入带引号的字符串(如'db_host'),可查普通常量、类常量('class::const')、接口常量及php 8.1+枚举case('enum::case'),不支持变量或函数检测,误用常见于引号缺失或混淆isset()与function_exists()。

defined() 只能检查常量,不能查变量、函数或类——这是它最常被误用的地方。
检查普通常量是否存在
直接传入常量名字符串,注意必须加单引号或双引号,否则 PHP 会尝试解析为已定义常量,报 Notice: Use of undefined constant 错误。
-
defined('DB_HOST')✅ 正确 -
defined(DB_HOST)❌ 报 Notice,除非DB_HOST真的已定义 -
defined("DB_HOST")✅ 也正确,但推荐单引号(语义更清晰)
典型用法是防止重复定义:
if (!defined('APP_ENV')) {
define('APP_ENV', 'development');
}
检查类常量和接口常量
类常量必须用完整作用域语法,包括双冒号,且整个字符串要加引号:
-
defined('MyClass::VERSION')✅ -
defined('MyClass::version')❌ 大小写敏感,即使类里定义的是小写也不行 -
defined(MyClass::VERSION)❌ 同样会触发解析,不是字符串字面量
接口常量同理:defined('MyInterface::FLAG')。
PHP 8.1+ 检查 enum case
枚举成员也支持,语法一致:
enum Status {
case Active;
case Inactive;
}
var_dump(defined('Status::Active')); // bool(true)
- 只认
'EnumName::CaseName'这种字符串形式 - 不支持动态拼接变量,比如
defined($enum . '::' . $case)虽然语法合法,但容易出错,建议先拼好再传 - 枚举 case 名称严格区分大小写
常见踩坑点
最容易忽略的是「引号缺失」和「混淆变量/常量检测」:
- 把
defined($name)当成“查变量是否存在”——错,该用isset($name) - 在配置文件中写
if (defined('DEBUG') && DEBUG) { ... },但如果DEBUG是布尔常量,而你忘了define('DEBUG', true),defined('DEBUG')就是false,后面不会执行,但也不会报错,调试时很难发现 - 用
defined()查魔术常量如__FILE__或__DIR__——它们永远存在,defined('__FILE__')总是true,没必要查
真正需要 defined() 的地方,几乎都出现在配置引导、插件兼容判断、或防止多次加载的守卫逻辑里;其他时候,多数是误用。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











