Often times when building plugins or themes, developers will choose to store specific information in the database like theme options, or settings. In these cases, many times the developer will choose to use “serialized data” to store this content in the database.
What is Serialized Data?
PHP has a function called serialize() which stores an array of data as a serialized row. This row looks something like this for my “active_plugins” row in wp_options:
a:8:{i:0;s:31:"query-monitor/query-monitor.php";i:1;s:57:"accesspress-instagram-feed/accesspress-instagram-feed.php";i:2;s:19:"akismet/akismet.php";i:3;s:29:"easy-captcha/easy-captcha.php";i:4;s:43:"google-analytics-dashboard-for-wp/gadwp.php";i:5;s:33:"instagram-feed/instagram-feed.php";i:6;s:19:"jetpack/jetpack.php";i:7;s:47:"really-simple-captcha/really-simple-captcha.php";}
That probably looks like a lot of nonsense, but in reality it’s just taking an array like this…
$array = array(
'0' => 'query-monitor/query-monitor.php'
'1' => 'accesspress-instagram-feed/accesspress-instagram-feed.php'
'2' => 'akismet/akismet.php'
'3' => 'easy-captcha/easy-captcha.php'
'4' => 'google-analytics-dashboard-for-wp/gadwp.php'
'5' => 'instagram-feed/instagram-feed.php'
'6' => 'jetpack/jetpack.php'
'7' => 'really-simple-captcha/really-simple-captcha.php'
);
…and putting it into text giving a count of total items in the list, as well as how many characters are on each line.
Potential Conflicts
Serialized data can work well for plugins or themes to store lists of items or settings, but sometimes conflicts can arise. The most common conflict by far comes up when copying your site to a new environment (for example a local dev environment, staging area, or a new install altogether). When making a copy, usually this will involve changing the URL of your site in the database. If your serialized data is storing your URL in it, like this:
a:1:{i:0;s:27:”http://example.wpengine.com”;}
Then for example, when your URL changes to your staging URL, it may update the domain in the process:
a:1:{i:0;s:27:”http://example.staging.wpengine.com”;}
But after this change, my character count (s:27) doesn’t match what follows! This invalidates the row.
So for example, if your theme options stored a full URL path for some settings or an image, it may end up showing default theme settings on the site instead of your custom settings. If you are performing a basic SQL search/replace on your site, it won’t be able to intelligently update these rows containing serialized data, because it won’t automatically update the character count. However, searching and replacing the database using PHP does not break the serialized rows, so this is definitely the recommended option.
When copying sites, there are a few options to search using PHP, so as to not break the serialized rows:
- When WP Engine copies between sites, or copies between environments, we search/replace using WP-CLI and regex to make sure serialized rows are not broken
- The Better Search Replace plugin automatically handles serialized data
- The Search and Replace plugin offers an option which handles serialized data
If you are running into issues with broken serialized data even when using one of the above methods, often times themes or plugins which store important data as serialized rows will offer an export option. With this option, you can export the settings, then import them to the new environment to fix the issue.