define()定义的常量天然全局可见,函数内外均可直接用常量名访问,因其注册于全局符号表,不依赖执行上下文,只要定义成功,整个脚本生命周期内任意位置(包括匿名函数、类方法)都能直接使用;但必须确保定义早于首次访问,否则触发undefined constant警告。
define() 定义的常量在 PHP 8.2 中天然全局可见,函数内外都能直接用常量名访问,不需要 global、不需要 use、也不需要额外声明。
define() 定义的常量为什么函数里能直接用define() 创建的是全局作用域常量,和变量的局部/全局规则完全无关;MY_CONST 访问;PI)时,会先查是否为已定义常量,再查是否为类常量,最后才报 Notice: Use of undefined constant。define() 常量的常见错误echo my_const; —— 少了引号且未定义:PHP 当作裸常量名解析,但若没定义过,会触发 Notice: Use of undefined constant my_const 并当作字符串字面量输出(PHP 8.2 默认开启 strict warnings);echo "value: $my_const"; —— 错误:变量插值语法只对 $var 有效,my_const 不是变量,不会被替换;define('ENV', 'prod'); function f() { echo ENV; } —— 正确,但若 define() 写在函数调用之后,而函数又提前执行(比如注册了 autoloader 或 register_shutdown_function),就会报未定义;define()(如 if ($debug) define('LOG_LEVEL', 'DEBUG');)—— 合法,但后续所有地方都得用 defined('LOG_LEVEL') 判断后再访问,否则可能 warning。define() 和 const 在函数内访问的区别define('A', 1):运行时定义,可放在任意位置(包括 if / for / 函数内),定义后全局生效;const A = 1;(顶层):编译时定义,必须在文件最外层,不能套在函数或条件里;const A = 1;(类内):只能通过 ClassName::A 访问,函数内直接写 A 会报错,除非用 self::A 或 static::A;const(顶层)略快;define() 更灵活,适合动态场景(比如根据环境文件决定常量值)。实际写法就两行够用:
<?phpdefine('API_TIMEOUT', 5000);function call_api() { return curl_setopt($ch, CURLOPT_TIMEOUT_MS, API_TIMEOUT);}
真正容易被忽略的点只有一个:常量定义必须早于首次访问。不是“写在前面就行”,而是“执行流到达访问点之前,define 必须已完成”。如果用 Composer autoloader 加载的文件里才定义常量,而你某个函数在 autoload 前就被调用了(比如 CLI 入口直接调函数),那就真会报未定义——这时候得靠 defined() 防御性检查,而不是指望作用域规则兜底。