調用 mhash() 報 Call to undefined function mhash(),通常是未安裝 php_mhash.dll 及依賴的 libmhash.dll。除編譯安裝擴展外,可採用純 PHP 實現的 hmac_md5() 兼容現有調用代碼,零依賴、即插即用。
php_mhash.dll 對應 PHP 版本/TS/NTS。libmhash.dll 放入系統 PATH(如 C:\Windows\System32 或 PHP 目錄)。httpd.conf 添加:LoadFile "C:/php/libmhash.dll"。php.ini 啟用:extension=php_mhash.dll。php -m | grep mhash。<?php
/**
* HMAC-MD5 兼容 mhash(MHASH_MD5, $data, $key)
* @param string $key 密鑰
* @param string $data 數據
* @return string 十六進制哈希字符串
*/
function hmac_md5($key, $data) {
// 若擴展存在,優先使用原生(性能更好)
if (extension_loaded('mhash')) {
return bin2hex(mhash(MHASH_MD5, $data, $key));
}
$b = 64; // MD5 分組長度(字節)
// 密鑰過長先哈希縮短
if (strlen($key) > $b) {
$key = pack('H*', md5($key));
}
// 密鑰補零至 64 字節
$key = str_pad($key, $b, chr(0x00));
// 内部/外部填充常量
$ipad = str_pad('', $b, chr(0x36)); // 0x36 = 54
$opad = str_pad('', $b, chr(0x5c)); // 0x5c = 92
// XOR 運算生成內/外部密鑰
$k_ipad = $key ^ $ipad;
$k_opad = $key ^ $opad;
// HMAC 核心:H(K ⊕ opad || H(K ⊕ ipad || data))
return md5($k_opad . pack('H*', md5($k_ipad . $data)));
}
// 原 mhash 調用
mhash(MHASH_MD5, $data, $key); // 參數順序:算法、數據、密鑰
// 兼容調用
hmac_md5($key, $data); // 參數順序:密鑰、數據(注意順序相反)
$key = 'secret_key';
$data = 'message to sign';
echo 'Native mhash: ' . (extension_loaded('mhash') ? bin2hex(mhash(MHASH_MD5, $data, $key)) : 'N/A') . "\n";
echo 'Pure PHP: ' . hmac_md5($key, $data) . "\n";
// 兩者輸出應完全一致
hash_hmac():PHP 5.1.2+ 內置 hash_hmac('md5', $data, $key),性能更優、API 標準、支持 SHA256/SHA512 等更強算法。hash_hmac('sha256', ...) 或 hash_hmac('sha512', ...)。純 PHP 兼容層能快速解決遷移期擴展缺失問題,長期建議統一遷移至 hash_hmac() + SHA2 系列算法,徹底擺脫舊擴展依賴。