unserialize() 返回 false,且不拋出例外。常見於跨系統、跨資料庫編碼環境序列化/反序列化不一致時。
PHP 序列化格式包含字串長度:s:29:"https://example.com"。若序列化時編碼為 UTF-8 (中文 3 位元組),反序列化時環境視為 Latin1 (單位元組),長度計算錯誤導致解析失敗。單雙引號、\0、\r 等特殊字元同理。
<?php
// UTF-8 環境修復
function mb_unserialize($serial_str) {
// 重新計算所有 s:長度:"值" 的實際位元組長度
$serial_str = preg_replace_callback(
'!s:(\d+):"(.*?)";!s',
function($m) { return 's:' . strlen($m[2]) . ':"' . $m[2] . '";'; },
$serial_str
);
$serial_str = str_replace("\r", '', $serial_str);
return unserialize($serial_str);
}
// ASCII/單位元組環境修復
function asc_unserialize($serial_str) {
$serial_str = preg_replace_callback(
'!s:(\d+):"(.*?)";!s',
function($m) { return 's:' . strlen($m[2]) . ':"' . $m[2] . '";'; },
$serial_str
);
$serial_str = str_replace("\r", '', $serial_str);
return unserialize($serial_str);
}
$bad = 'a:9:{s:4:"time";i:1405306402;s:5:"name";s:6:"新晨";s:5:"url";s:1:"-";s:4:"word";s:1:"-";s:5:"rpage";s:29:"https://www.baidu.com/test.html";s:5:"cpage";s:1:"-";s:2:"ip";s:15:"117.151.180.150";s:7:"ip_city";s:31:"中國北京市 北京市移動";s:4:"miao";s:1:"5";}';
var_dump(unserialize($bad)); // bool(false)
var_dump(mb_unserialize($bad)); // 正常陣列
SET NAMES utf8mb4, default_charset = "UTF-8" )。serialize() 產生。json_encode/json_decode 無長度前綴問題、跨語言相容、可讀性佳。base64_encode(serialize($data)),讀取後 unserialize(base64_decode($str)),繞過編碼轉換層。unserialize 失敗多因序列化與反序列化環境編碼不一致導致長度前綴錯誤。mb_unserialize 透過正則重算長度可應急修復,但根治之道在於全鏈路 UTF-8 標準化或改用 JSON 格式儲存。