fbpx
Search
Close this search box.

Home / Blog

 / 
How to fix a broken serialization

How to fix a broken serialization

Serialization is a way to store multidimensional data as a string. It’s commonly used in the WordPress database, because of the architecture of the tables. When it breaks (for various reasons) it’s a disaster. But not with our handy-dandy scripts.

Fixing a database dump with broken serialization

Steps are simple:

  1. Create the database dump (you should have a .sql file)
  2. Run the script: `php ./fix-serialization.php database.sql`
  3. Upload the .sql file back to the server

The script has been created by an awesome WordPress developer – Wojtek Szałkiewicz.

Recovering the corrupted serialized array

If you have a variable with a string which cannot be unserialized, try to use the below function:

/**
* Extract what remains from an unintentionally truncated serialized string
*
* @param string The serialized array
*/
public function repairSerializedArray($serialized)
{
    $tmp = preg_replace('/^a:\d+:\{/', '', $serialized);
    return $this->repairSerializedArray_R($tmp); // operates on and whittles down the actual argument
}

/**
* The recursive function that does all of the heavy lifing. Do not call directly.

* @param string The broken serialzized array
* @return string Returns the repaired string
*/
private function repairSerializedArray_R(&$broken)
{
    // array and string length can be ignored
    // sample serialized data
    // a:0:{}
    // s:4:"four";
    // i:1;
    // b:0;
    // N;
    $data		= array();
    $index		= null;
    $len		= strlen($broken);
    $i			= 0;

    while(strlen($broken))
    {
        $i++;
        if ($i > $len)
        {
            break;
        }

        if (substr($broken, 0, 1) == '}') // end of array
        {
            $broken = substr($broken, 1);
            return $data;
        }
        else
        {
            $bite = substr($broken, 0, 2);
            switch($bite)
            {	
                case 's:': // key or value
                    $re = '/^s:\d+:"([^\"]*)";/';
                    if (preg_match($re, $broken, $m))
                    {
                        if ($index === null)
                        {
                            $index = $m[1];
                        }
                        else
                        {
                            $data[$index] = $m[1];
                            $index = null;
                        }
                        $broken = preg_replace($re, '', $broken);
                    }
                break;

                case 'i:': // key or value
                    $re = '/^i:(\d+);/';
                    if (preg_match($re, $broken, $m))
                    {
                        if ($index === null)
                        {
                            $index = (int) $m[1];
                        }
                        else
                        {
                            $data[$index] = (int) $m[1];
                            $index = null;
                        }
                        $broken = preg_replace($re, '', $broken);
                    }
                break;

                case 'b:': // value only
                    $re = '/^b:[01];/';
                    if (preg_match($re, $broken, $m))
                    {
                        $data[$index] = (bool) $m[1];
                        $index = null;
                        $broken = preg_replace($re, '', $broken);
                    }
                break;

                case 'a:': // value only
                    $re = '/^a:\d+:\{/';
                    if (preg_match($re, $broken, $m))
                    {
                        $broken			= preg_replace('/^a:\d+:\{/', '', $broken);
                        $data[$index]	= $this->repairSerializedArray_R($broken);
                        $index = null;
                    }
                break;

                case 'N;': // value only
                    $broken = substr($broken, 2);
                    $data[$index]	= null;
                    $index = null;
                break;
            }
        }
    }

    return $data;
}

The usage is simple:

$data = @unserialize( $serialized );

if ( false === $data ) {
    $data = repairSerializedArray( $serialized );
}

Let me know in the comments if it worked in your case! 👨‍💻

Share This Article:

Picture of Kuba Mikita

Kuba Mikita

Share This Article:

Summary

Picture of Kuba Mikita

Kuba Mikita

Share This Article:

Latest updates, discounts and more!

Get the most recent updates on WordPress automation, fresh plugins, new features and price cuts.

Related articles

Following the success of the Notification plugin, we knew that personalization was the direction we would pursue. Thanks to feedback, we were easily able to identify the needs of the...

WordPress Cron is pretty basic and doesn’t allow for much configuration in terms of schedules. By default, you can run your events with a specific interval, like daily, weekly, or...

As a marketer diving into the technical realm, I’ve often highlighted the benefits of implementing a notification strategy on WordPress sites. Now, it’s time to delve into a more technical...

WordPress Plugins that get the job done

With years of experience creating client websites, we bring our experience to functional WordPress plugins.

Easy to use for everyone

Regardless of experience level, you can easily use our products.

Top-notch Support included

We treat our clients seriously and focus heavily on support. Reviews backs this up!

Extensible and developer friendly

You're the same developer as we are. Our code is clean and extensible, just the way you like.