首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Regex/ code修复损坏的序列化PHP数据。

Regex/ code修复损坏的序列化PHP数据。
EN

Stack Overflow用户
提问于 2010-06-30 19:23:28
回答 10查看 18.8K关注 0票数 20

我有一个庞大的多维数组,已经被PHP序列化了。它已存储在MySQL中,数据字段不够大...末端被切断了..。我需要提取数据。unserialize不工作..。有没有人知道可以关闭所有数组的代码...重新计算字符串长度...手工处理的数据量太大了。

非常感谢。

EN

回答 10

Stack Overflow用户

回答已采纳

发布于 2010-06-30 19:36:36

我认为这几乎是不可能的。在修复阵列之前,您需要知道阵列是如何损坏的。有多少孩子失踪了?内容是什么?

对不起,imho,你不能这么做。

证明:

<?php

$serialized = serialize(
    [
        'one'   => 1,
        'two'   => 'nice',
        'three' => 'will be damaged'
    ]
);

var_dump($serialized); // a:3:{s:3:"one";i:1;s:3:"two";s:4:"nice";s:5:"three";s:15:"will be damaged";}

var_dump(unserialize('a:3:{s:3:"one";i:1;s:3:"two";s:4:"nice";s:5:"tee";s:15:"will be damaged";}')); // please note 'tee'

var_dump(unserialize('a:3:{s:3:"one";i:1;s:3:"two";s:4:"nice";s:5:"three";s:')); // serialized string is truncated

链接:https://ideone.com/uvISQu

即使您可以重新计算键/值的长度,您也不能信任从该源检索到的数据,因为您无法重新计算这些值。例如:如果序列化的数据是一个对象,那么您的属性将不再可访问。

票数 -5
EN

Stack Overflow用户

发布于 2011-04-07 20:28:11

这是重新计算序列化数组中元素的长度:

$fixed = preg_replace_callback(
    '/s:([0-9]+):\"(.*?)\";/',
    function ($matches) { return "s:".strlen($matches[2]).':"'.$matches[2].'";';     },
    $serialized
);

但是,如果字符串包含";,则它不起作用。在这种情况下,不可能自动修复序列化的数组字符串--需要手动编辑。

票数 38
EN

Stack Overflow用户

发布于 2015-12-11 21:13:38

我尝试了在这篇文章中找到的所有东西,但都没有对我起作用。在经历了几个小时的痛苦之后,我在谷歌的深层页面中找到了一些东西,并最终成功了:

function fix_str_length($matches) {
    $string = $matches[2];
    $right_length = strlen($string); // yes, strlen even for UTF-8 characters, PHP wants the mem size, not the char count
    return 's:' . $right_length . ':"' . $string . '";';
}
function fix_serialized($string) {
    // securities
    if ( !preg_match('/^[aOs]:/', $string) ) return $string;
    if ( @unserialize($string) !== false ) return $string;
    $string = preg_replace("%\n%", "", $string);
    // doublequote exploding
    $data = preg_replace('%";%', "µµµ", $string);
    $tab = explode("µµµ", $data);
    $new_data = '';
    foreach ($tab as $line) {
        $new_data .= preg_replace_callback('%\bs:(\d+):"(.*)%', 'fix_str_length', $line);
    }
    return $new_data;
}

您可以按如下方式调用该例程:

//Let's consider we store the serialization inside a txt file
$corruptedSerialization = file_get_contents('corruptedSerialization.txt');

//Try to unserialize original string
$unSerialized = unserialize($corruptedSerialization);

//In case of failure let's try to repair it
if(!$unSerialized){
    $repairedSerialization = fix_serialized($corruptedSerialization);
    $unSerialized = unserialize($repairedSerialization);
}

//Keep your fingers crossed
var_dump($unSerialized);
票数 18
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3148712

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档