Đoạn mã sau sẽ cố gắng đọc & phân tích chuỗi được tuần tự bị hỏng đệ quy (dữ liệu blob). Ví dụ, nếu bạn được lưu trữ trong chuỗi cột cơ sở dữ liệu quá dài và nó đã bị cắt bỏ. Các số nguyên tố và bool được đảm bảo là hợp lệ, các chuỗi có thể bị cắt bỏ và/hoặc các khóa mảng có thể bị thiếu. Thông lệ có thể hữu ích, ví dụ: nếu khôi phục phần đáng kể (không phải tất cả) dữ liệu là giải pháp đủ cho bạn.
class Unserializer
{
/**
* Parse blob string tolerating corrupted strings & arrays
* @param string $str Corrupted blob string
*/
public static function parseCorruptedBlob(&$str)
{
// array pattern: a:236:{...;}
// integer pattern: i:123;
// double pattern: d:329.0001122;
// boolean pattern: b:1; or b:0;
// string pattern: s:14:"date_departure";
// null pattern: N;
// not supported: object O:{...}, reference R:{...}
// NOTES:
// - primitive types (bool, int, float) except for string are guaranteed uncorrupted
// - arrays are tolerant to corrupted keys/values
// - references & objects are not supported
// - we use single byte string length calculation (strlen rather than mb_strlen) since source string is ISO-8859-2, not utf-8
if(preg_match('/^a:(\d+):{/', $str, $match)){
list($pattern, $cntItems) = $match;
$str = substr($str, strlen($pattern));
$array = [];
for($i=0; $i<$cntItems; ++$i){
$key = self::parseCorruptedBlob($str);
if(trim($key)!==''){ // hmm, we wont allow null and "" as keys..
$array[$key] = self::parseCorruptedBlob($str);
}
}
$str = ltrim($str, '}'); // closing array bracket
return $array;
}elseif(preg_match('/^s:(\d+):/', $str, $match)){
list($pattern, $length) = $match;
$str = substr($str, strlen($pattern));
$val = substr($str, 0, $length + 2); // include also surrounding double quotes
$str = substr($str, strlen($val) + 1); // include also semicolon
$val = trim($val, '"'); // remove surrounding double quotes
if(preg_match('/^a:(\d+):{/', $val)){
// parse instantly another serialized array
return (array) self::parseCorruptedBlob($val);
}else{
return (string) $val;
}
}elseif(preg_match('/^i:(\d+);/', $str, $match)){
list($pattern, $val) = $match;
$str = substr($str, strlen($pattern));
return (int) $val;
}elseif(preg_match('/^d:([\d.]+);/', $str, $match)){
list($pattern, $val) = $match;
$str = substr($str, strlen($pattern));
return (float) $val;
}elseif(preg_match('/^b:(0|1);/', $str, $match)){
list($pattern, $val) = $match;
$str = substr($str, strlen($pattern));
return (bool) $val;
}elseif(preg_match('/^N;/', $str, $match)){
$str = substr($str, strlen('N;'));
return null;
}
}
}
// usage:
$unserialized = Unserializer::parseCorruptedBlob($serializedString);
Đây có thể là một nguồn tài nguyên hữu ích cho một số người tìm kiếm câu hỏi này - Tôi đã sử dụng nó nhiều lần và nó làm việc tốt mỗi lần: https://github.com/Blogestudio/Fix-Serialization (được cấp điều này có thể sẽ không giúp ích khi phần lớn chuỗi bị cắt - chỉ khi bạn đã thực hiện tìm kiếm và thay thế và độ dài chuỗi là off) – billynoah