用于修复损坏的序列化PHP数据的正则表达式/代码

Sim*_*mon 15 php

我有一个由PHP序列化的大型多维数组.它已存储在MySQL中,并且数据字段不够大......结束已被切断...我需要提取数据...... unserialize不会工作...有没有人知道可以关闭的代码所有的数组...重新计算字符串长度...手工做的数据太多了.

非常感谢.

Emi*_*l M 33

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

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

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

  • 包含双引号的字符串自上次使用";"进行编辑后起作用 添加 (2认同)

Mis*_*lad 17

我已经尝试过这篇文章中的所有内容,但对我来说没有任何作用 经过几个小时的痛苦,这是我在google的深层页面中发现的,最后工作:

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;
}
Run Code Online (Sandbox Code Playgroud)

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

//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);
Run Code Online (Sandbox Code Playgroud)


T.T*_*dua 11

解:

1)在线尝试:

序列化字符串修复程序(在线工具)

2)使用功能:

unserialize( serialize_corrector($serialized_string ) ) ;

码:

function serialize_corrector($serialized_string){
    // at first, check if "fixing" is really needed at all. After that, security checkup.
    if ( @unserialize($serialized_string) !== true &&  preg_match('/^[aOs]:/', $serialized_string) ) {
         $serialized_string = preg_replace_callback( '/s\:(\d+)\:\"(.*?)\";/s',    function($matches){return 's:'.strlen($matches[2]).':"'.$matches[2].'";'; },   $serialized_string );
    }
    return $serialized_string;
} 
Run Code Online (Sandbox Code Playgroud)


fab*_*rik -5

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

抱歉,恕我直言,你做不到。

证明:

<?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
Run Code Online (Sandbox Code Playgroud)

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

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