PHP Serialization Fix for WordPress Migrations (& other applications like Expression Engine)

A different kind of migration - public domain from Wikipedia Commons

A different kind of migration - public domain from Wikipedia Commons

When you move a WordPress blog from one folder to another, or from one site to another, you normally use the export/import functionality.

This is fine for normal blogs, but say you’ve developed a new website and set it up on your local machine – the URL for the site may be something like http://localhost/devsite and the live URL will be something like http://www.davesgonemental.com – you won’t want to set up all the theme options, site options, plugin options and so on all over again.

Instead, a theoretically simple approach is to do a database dump, a search and replace for all references to server paths and URLs, and then reimport that data in the new location.

Should work, but it often falls apart.

What happens is that in WordPress, its themes and its plugins, a lot of data is stored using a method known as serialization.  Now, in my opinion this breaks all known good practice around data – it’s language specific, it’s not relational even though it often could be, and it’s hard to edit by hand.

One particular problem is that if you change the length of the data in a serialised string you have to change the length declared in the generated string.

That’s very painful when you have hundreds of the fields.

So, because I’d found this painful I decided to knock together a quick application to at least reduce the amount of editing I had to do.  You just do your search and replace, forget about the serialized string lengths, upload your data to the new database, and run this script.

Warning: I haven’t got it to work for widgets and cForms II yet, but the latter has some export functionality anyway, which takes that particular pain away if you plan ahead.  In the meantime, feel free to play with the attached file.  You use it at your own risk, of course.

To use it, download the file linked in this post, extract it, open the file, edit the connection settings, tell it the table you want to scan through, the column, and the unique key field.  If you somehow manage to have more than one unique key to deal with (you shouldn’t, but then it surprises me what people manage to code up), then you’ll have to modify the code accordingly.  Once done, make sure you have a backup of that table, and execute the php – either at the command line or through the browser. License is WTFPL, and if you’d like to improve the code, please do and I’ll host the new version.

Serialization-fixer.zip download.

download file

Serialization-fixer.zip download

BIG WARNING: I take no responsibility for what this code does to your data. Use it at your own risk. Test it. Be careful. OK? Here in the North we might describe the code as being as “Rough as a badger’s arse.” Never felt a badger’s arse, but I’ll take their word for it.

Comments
  • Threaded commenting powered by Spectacu.la code.

  • Scott Kingsley Clark 22 August, 2010 at 12:46 am

    WOW! Thank you so much for this! I can’t believe it worked so well, I’m not even using it for WP specifically, but a plugin that stores some values in a serialized array and I had edited it in the db and adjusted the count of the string, but saving it completely busted open the array from being unserialized. Running it through this filter fixed it right up! Thanks again for your contribution Dave!

  • Burton Kent 10 April, 2009 at 2:57 pm

    Interesting! I just wrote a script to copy a wordpress install to a new domain, and am running into the exact same problem. The script works except for widgets.

    Any idea exactly what part of widgets is being broken? Maybe I can figure it out for both of us.

    Thanks!

    • Dave 10 April, 2009 at 4:13 pm

      Burton – I think the problem is down to nested arrays – it’s just too hard a problem for my simple regex fix to solve.

      What’s needed instead is a script to read a database, pick up what’s serialized php, unserialize it, carry out the search and replace, and then re-serialize the data and put it back into the database. But that’s a considerably bigger job.

      My script is, essentially, a sticking plaster to fix most of the problems. You could do the widgets by hand – at least then there’s not too much to do. Everything else seems to be OK, though I’ve noticed some plugins like cFormsII do this too, so that’s another manual job.

  • Sean Gravener 9 April, 2009 at 2:09 pm

    “Ultimately, there needs to be a simple way for people to easily and quickly change values in serialized data”

    Agreed!!

  • Sean Gravener 8 April, 2009 at 10:40 pm

    You should label it not only to fix WordPress, but as a general fix for corrupted serialized database records – being able to define the db, table, index and column makes it flexible.

    Perhaps the next step would be allowing a user to define an array of table columns instead of one at a time… and perhaps echoing a status at the end :)

    Maybe even a clever name…

    In any case, it’s a big help as is.

    • Dave 9 April, 2009 at 7:49 am

      Aye – good point. I wrote it to solve a very specific problem, using snippets I’d found elsewhere but wrapped up in a single script.

      I’m planning to write a script that lets you do a search and replace on a table or even entire database, deserializing and reserializing as necessary. Ultimately, there needs to be a simple way for people to easily and quickly change values in serialized data. Alternatively, PHP developers could just learn some good database practices, but I’m not holding my breath ;-)

  • Sean Gravener 7 April, 2009 at 8:56 pm

    You’re a life saver, Dave. I used this script to fix serialization issues in Expression Engine… many thanks.

    • Dave 8 April, 2009 at 9:39 pm

      Thanks Sean – glad to hear it was useful for you. When you put these things out you never know whether it’ll help people or not – gives a nice warm fuzzy feeling to hear that it does :-)

Trackbacks