Regex/ code to fix corrupt serialized PHP data.

前端 未结 12 731
夕颜
夕颜 2020-11-30 07:04

I have a massive multidimensional array that has been serialised by PHP. It has been stored in MySQL and the data field wasn\'t large enough... the end has been cut off... I

12条回答
  •  伪装坚强ぢ
    2020-11-30 07:22

    [UPD] Colleagues, I'm not very sure if it is allowed here, but specially for similar cases I've created own tool and 've placed it on own website. Please, try it https://saysimsim.ru/tools/SerializedDataEditor

    [Old text] Conclusion :-) After 3 days (instead of 2 estimated hours) migrating blessed WordPress website to a new domain name, I've finally found this page!!! Colleagues, please, consider it as my "Thank_You_Very_Much_Indeed" to all your answers. The code below consists of all your solutions with almost no additions. JFYI: personally for me the most often SOLUTION 3 works. Kamal Saleh - you are the best!!!

    function hlpSuperUnSerialize($str) {
        #region Simple Security
        if (
            empty($str)
            || !is_string($str)
            || !preg_match('/^[aOs]:/', $str)
        ) {
            return FALSE;
        }
        #endregion Simple Security
    
        #region SOLUTION 0
        // PHP default :-)
        $repSolNum = 0;
        $strFixed  = $str;
        $arr       = @unserialize($strFixed);
        if (FALSE !== $arr) {
            error_log("UNSERIALIZED!!! SOLUTION {$repSolNum} worked!!!");
    
            return $arr;
        }
        #endregion SOLUTION 0
    
        #region SOLUTION 1
        // @link https://stackoverflow.com/a/5581004/3142281
        $repSolNum = 1;
        $strFixed  = preg_replace_callback(
            '/s:([0-9]+):\"(.*?)\";/',
            function ($matches) { return "s:" . strlen($matches[2]) . ':"' . $matches[2] . '";'; },
            $str
        );
        $arr       = @unserialize($strFixed);
        if (FALSE !== $arr) {
            error_log("UNSERIALIZED!!! SOLUTION {$repSolNum} worked!!!");
    
            return $arr;
        }
        #endregion SOLUTION 1
    
        #region SOLUTION 2
        // @link https://stackoverflow.com/a/24995701/3142281
        $repSolNum = 2;
        $strFixed  = preg_replace_callback(
            '/s:([0-9]+):\"(.*?)\";/',
            function ($match) {
                return "s:" . strlen($match[2]) . ':"' . $match[2] . '";';
            },
            $str);
        $arr       = @unserialize($strFixed);
        if (FALSE !== $arr) {
            error_log("UNSERIALIZED!!! SOLUTION {$repSolNum} worked!!!");
    
            return $arr;
        }
        #endregion SOLUTION 2
    
        #region SOLUTION 3
        // @link https://stackoverflow.com/a/34224433/3142281
        $repSolNum = 3;
        // securities
        $strFixed = preg_replace("%\n%", "", $str);
        // doublequote exploding
        $data     = preg_replace('%";%', "µµµ", $strFixed);
        $tab      = explode("µµµ", $data);
        $new_data = '';
        foreach ($tab as $line) {
            $new_data .= preg_replace_callback(
                '%\bs:(\d+):"(.*)%',
                function ($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 . '";';
                },
                $line);
        }
        $strFixed = $new_data;
        $arr      = @unserialize($strFixed);
        if (FALSE !== $arr) {
            error_log("UNSERIALIZED!!! SOLUTION {$repSolNum} worked!!!");
    
            return $arr;
        }
        #endregion SOLUTION 3
    
        #region SOLUTION 4
        // @link https://stackoverflow.com/a/36454402/3142281
        $repSolNum = 4;
        $strFixed  = preg_replace_callback(
            '/s:([0-9]+):"(.*?)";/',
            function ($match) {
                return "s:" . strlen($match[2]) . ":\"" . $match[2] . "\";";
            },
            $str
        );
        $arr       = @unserialize($strFixed);
        if (FALSE !== $arr) {
            error_log("UNSERIALIZED!!! SOLUTION {$repSolNum} worked!!!");
    
            return $arr;
        }
        #endregion SOLUTION 4
    
        #region SOLUTION 5
        // @link https://stackoverflow.com/a/38890855/3142281
        $repSolNum = 5;
        $strFixed  = preg_replace_callback('/s\:(\d+)\:\"(.*?)\";/s', function ($matches) { return 's:' . strlen($matches[2]) . ':"' . $matches[2] . '";'; }, $str);
        $arr       = @unserialize($strFixed);
        if (FALSE !== $arr) {
            error_log("UNSERIALIZED!!! SOLUTION {$repSolNum} worked!!!");
    
            return $arr;
        }
        #endregion SOLUTION 5
    
        #region SOLUTION 6
        // @link https://stackoverflow.com/a/38891026/3142281
        $repSolNum = 6;
        $strFixed  = preg_replace_callback(
            '/s\:(\d+)\:\"(.*?)\";/s',
            function ($matches) { return 's:' . strlen($matches[2]) . ':"' . $matches[2] . '";'; },
            $str);;
        $arr = @unserialize($strFixed);
        if (FALSE !== $arr) {
            error_log("UNSERIALIZED!!! SOLUTION {$repSolNum} worked!!!");
    
            return $arr;
        }
        #endregion SOLUTION 6
        error_log('Completely unable to deserialize.');
    
        return FALSE;
    }
    

提交回复
热议问题