
PHP里用 define() 还是 const?
直接说结论:新项目优先用 const(尤其类内和命名空间下),全局简单常量可用 define()),但别混着用。两者不是功能等价,而是语义和作用域不同。
常见错误是以为 define('PI', 3.14) 和 const PI = 3.14; 可以随意替换——其实 const 在 PHP 5.6+ 支持表达式(如 const MAX = 1024 * 1024;),而 define() 的值必须是字面量或变量,不能是函数调用;反过来,define() 能动态拼接名称(define('CACHE_' . $env, true)),const 不行。
-
const是语言结构,编译期解析,性能略好;define()是函数,运行时执行 - 类中只能用
const(public const VERSION = '1.0';),不能用define() - 命名空间下推荐
const:namespace App; const DB_HOST = 'localhost';,define()会定义到全局空间
为什么 defined('FOO') 检查总返回 false?
不是没定义,大概率是作用域或大小写问题。PHP 常量名默认区分大小写,且一旦定义就不可修改,但检查前得确认它真在当前作用域可见。
典型场景:在函数里用 define('DEBUG', true),然后在另一个文件里 defined('DEBUG') 返回 false——因为 define() 是全局的,但如果你用了 require 顺序错,或者常量定义被 if (false) 包住了,实际根本没执行到定义语句。
立即学习“PHP免费学习笔记(深入)”;
十天学会易语言图解教程用图解的方式对易语言的使用方法和操作技巧作了生动、系统的讲解。需要的朋友们可以下载看看吧!全书分十章,分十天讲完。 第一章是介绍易语言的安装,以及运行后的界面。同时介绍一个非常简单的小程序,以帮助用户入门学习。最后介绍编程的输入方法,以及一些初学者会遇到的常见问题。第二章将接触一些具体的问题,如怎样编写一个1+2等于几的程序,并了解变量的概念,变量的有效范围,数据类型等知识。其后,您将跟着本书,编写一个自己的MP3播放器,认识窗口、按钮、编辑框三个常用组件。以认识命令及事件子程序。第
- 检查是否拼错名:
defined('DeBuG')≠defined('DEBUG') - 确认定义代码已执行:把
echo 'here';放在define()前,看是否输出 - 避免在条件块里定义常量,除非你明确知道该分支一定会走
- 用
get_defined_constants(true)['user']查看当前所有用户定义常量(调试时很有用)
$_SERVER['DOCUMENT_ROOT'] 算常量还是变量?能改吗?
它是个超全局数组元素,不是常量。名字带 ROOT 容易误导人,但它本质是运行时由 Web 服务器注入的变量,值可能因部署环境变化(如 Docker、Nginx alias、Apache Alias 指令)而不同。
常见坑是硬编码路径拼接:include $_SERVER['DOCUMENT_ROOT'] . '/inc/config.php';,结果在 CLI 模式下 $_SERVER['DOCUMENT_ROOT'] 为空或未定义,直接报错。
- CLI 下
$_SERVER['DOCUMENT_ROOT']通常不存在,要用__DIR__或dirname(__FILE__)替代 - 不要对它做
define('DOC_ROOT', $_SERVER['DOCUMENT_ROOT'])再到处用——如果后续chdir()或set_include_path(),这个“根”就失效了 - 更可靠的方式是用 Composer 自动加载,或统一用
__DIR__相对定位配置文件
常量值里放数组或对象会怎样?
PHP 5.6+ 允许 const 定义数组(const STATUS_MAP = ['active' => 1, 'inactive' => 0];),但不支持对象、资源、闭包、null(注意:PHP 7.4+ 支持 null)。define() 则完全不支持数组——它会静默转成字符串 "Array",然后你就得到一个永远为真的假常量。
错误示例:define('CONFIG', ['db' => 'mysql']); var_dump(CONFIG); // string(5) "Array",这比报错还危险,因为逻辑照常跑,只是数据丢了。
- 数组常量只支持
const,且必须是字面量(不能含变量或函数调用) - 需要动态数组?用静态属性代替:
class Config { public static array $map = []; } - 想让常量“可变”?说明设计有问题——常量就是不该变,换思路用配置类或 DI 容器
最易被忽略的一点:常量定义后无法 unset,也无法重定义,哪怕在不同文件里重复 const FOO = 1;,PHP 会直接 fatal error。所以模块化项目里,务必确保常量名唯一,别依赖“后定义覆盖前定义”这种幻想。










