根本原因是PHP 8.0严格禁止未加引号的裸标识符(如where('name=?', thumb)),而PHP 7.4会隐式转为字符串;需将所有裸词补上单引号,并检查define/const作用域及加载顺序。
PHP 7.4 升级到 8.0 后报
,根本原因不是常量没定义,而是你写了没加引号的标识符——PHP 8.0 不再容忍这种写法,直接当“未定义常量”报警告,而 PHP 7.4 会悄悄把它转成字符串(仅在
关闭时“看起来能跑”)。
为什么
会触发 Undefined constant 报错
典型错误代码长这样:
这里的
没加引号、前面没
,也不是已定义的常量(比如没用
),PHP 8.0 就严格按规范报错;PHP 7.4 则默认当作字符串
处理(并抛
,但很多项目关了 notice 显示,所以“没看见就等于没发生”)。
检查所有
、
类写法,
这类裸词必须加单引号或双引号
注意模板文件(如
混写 HTML 的地方)也容易漏引号,比如
虽然 HTML 合法,但在 PHP 字符串拼接里写成
就会触发该警告
搜索命令推荐:
(粗筛裸标识符,需人工确认)
和
声明后仍报错的常见原因
即使你写了
,还是报
,大概率是作用域或加载顺序问题:
PHP 8.5.5
PHP 8.5.5 是 PHP 8.5 分支的维护更新版本。该版本延续了“小步快跑”的迭代逻辑,通过深度错误修复、底层性能微调以及安全加固,旨在为开发者提供一个更健壮、更高效的运行环境。该版本严格遵守语义化版本规范,不包含破坏性变更。
下载
立即学习
“
PHP免费学习笔记(深入)
”;
必须在使用前执行,如果写在某个函数里、或被
晚于调用位置,就会失效
是类内常量,不能在类外直接写
,得用
命名空间下定义的常量(
)必须用全名
或
,不能裸写
CLI 环境和 Web 环境的配置文件加载路径可能不同,检查
是否真被引入(比如 Typecho 需确认
开启后是否真加载了全部配置)
怎么快速定位所有潜在裸常量问题
别靠肉眼扫,用 PHP 自带工具暴露隐患:
临时在入口文件开头加:
(仅开发环境!)
用
只能查语法,不报常量问题;必须实际运行才能触发 —— 所以要覆盖所有路由/脚本分支
启用
(PHP 8.0+),配合日志看哪些文件反复出现该警告
对 Composer 项目,加一行
,然后
强制跑出所有 warning
最易被忽略的是:这个报错在 PHP 8.0 下是
,但如果你开了
且
,某些框架会把 warning 转成 exception,导致整个请求中断——它看起来像 Fatal error,其实源头还是那个没引号的
。
Warning: Use of undefined constantE_NOTICEthumb$post[0]['thumb'] = $this->db->fetchAll($this->db->select('str_value')->from('table.fields')->where('cid = ?', $cid)->where('name = ? ', thumb)) ? ... : ...;thumb$define('thumb', 'xxx')'thumb'E_NOTICEwhere('name = ? ', thumb)array('key' => value)thumb.php""grep -r "[^$'][a-zA-Z_][a-zA-Z0-9_]*[^$'"\(\)\[\]\{\}]" app/ --include="*.php"define()constdefine('thumb', 'thumbnail');Undefined constantdefine()requireconst THUMB = 'thumbnail';THUMBClassName::THUMBnamespace Foo; const BAR = 1;FooBARuse const FooBAR;BARconfig.inc.php__TYPECHO_DEBUG__error_reporting(E_ALL); ini_set('display_errors', '1');php -l 文件名.phpopcache.record_warnings=1"scripts": {"compat-check": "php -d error_reporting=32767 -d display_errors=1 index.php"}composer run compat-checkWarningzend.assertions = 1assert.exception = 1thumb