能,hash_hmac() 在 PHP 8.0 中完全可用且行为与 7.4 一致;真正变化是参数类型校验更严格(null/array 报 TypeError)、算法名大小写敏感、废弃别名(如 "tiger")不再支持,需显式字符串化输入并使用标准算法名。

PHP 8.0 中 hash_hmac() 还能用吗?
能,完全可用,且行为与 PHP 7.4 一致——hash_hmac() 不在被移除之列。PHP 8.0 移除的是 mcrypt_* 系列函数(如 mcrypt_encrypt())、mysql_* 扩展,以及部分废弃的哈希算法别名(比如 "tiger" 的某些变体别名),但 hash_hmac() 本身是 hash 扩展的核心函数,未受影响。
真正要注意的是:如果你的代码依赖了已被弃用或移除的底层算法(例如硬编码使用 "ripemd160" 但运行环境没启用 hash 扩展),会报 Unknown hashing algorithm 错误;不是 hash_hmac() 函数没了,而是它要调用的算法不可用。
PHP 7.4 升级到 8.0 后 HMAC 验证失败的常见原因
不是算法失效,而是参数校验更严格、类型隐式转换被收紧。典型表现是:hash_hmac('sha256', $data, $key) 在 PHP 7.4 返回结果,但在 PHP 8.0 返回 false 或空字符串。
-
$data或$key是null、array或对象且未实现__toString()—— PHP 8.0 直接报TypeError,而 7.4 可能静默转成""或"Array" - 传入了非字符串的
$algo(比如数字256误当"sha256"),PHP 8.0 拒绝解析,7.4 可能尝试强制转换后“凑合用” - 使用了已废弃的算法别名,例如
"haval128"(正确应为"haval128,3")—— PHP 8.0 不再容忍模糊匹配
如何安全迁移 HMAC 相关代码到 PHP 8.0+
重点不是重写 hash_hmac() 调用,而是加固输入和明确算法声明:
立即学习“PHP免费学习笔记(深入)”;
- 对
$data和$key显式做(string)强制转换,避免null或数组触发 TypeError:hash_hmac('sha256', (string)$data, (string)$key) - 用
hash_algos()动态检查算法是否可用,而非硬编码假设:in_array('sha256', hash_algos()) - 避免使用缩写或旧别名;始终用标准名称,如
"sha256"、"sha512"、"haval160,4" - 如果原来用
hash_init()+hash_update()+hash_hmac_final()流式处理,确认hash_hmac_final()的第二个参数($key)类型也做了字符串化
PHP 8.0 中哪些哈希相关函数/算法确实不能用了?
以下内容在 PHP 8.0 中被彻底移除或禁用,若代码中存在,必须替换:
-
hash_hmac_file()仍存在,但若传入的文件路径是null或非字符串,会直接 TypeError(7.4 可能返回false) - 算法名
"snefru256"和"snefru128"已从hash_algos()列表中剔除(Snefru 算法因安全性问题被弃用) -
hash("tiger", $data, false)中的"tiger"作为简写不再识别;必须写全"tiger128,3"、"tiger160,3"等具体变体 - 所有
crypt()的非标准盐格式(如过短、含非法字符)在 PHP 8.0 中会返回"*0"或抛出警告,影响基于crypt()的 HMAC 兼容层逻辑
最易被忽略的点:本地开发用 PHP 7.4 测试通过,但生产环境 PHP 8.0 因扩展配置不同(比如 hash 扩展未启用),导致 hash_hmac() 函数根本不存在——上线前务必用 function_exists('hash_hmac') 做兜底判断。



















