When you move a WordPress website from one domain to another, you usually need to change the URLs in the database. Recently, I migrated my website from https://old-website.phpdev.top to https://new-website.top and ran into a tricky problem with serialized data.
The Problem
If you just use a simple SQL REPLACE query, you will break your database. This happens because PHP serialized objects store the exact length of the strings inside them.
For example, here is a piece of data from my database:
a:1:{i:0;a:2:{s:4:"name";s:13:"Custom Avatar";s:3:"url";s:75:"https://old-website.phpdev.top/wp-content/themes/itrem/images/noavatar.png";}}
Look at s:69. It means the URL inside the quotes has exactly 75 characters.
- My old domain name
https://old-website.phpdev.top/has 32 characters. - My new domain name
https://has only 25 characters.new-website.top/
If I just change the text, the URL becomes shorter, but PHP will still look for 75 characters. As a result, WordPress will not be able to read this data, and the website will break.
The Solution: WP-CLI
The best way to fix this is to use WP-CLI (WordPress Command Line Interface). This tool automatically unpacks the serialized data, replaces the text, recalculates the correct string length, and saves it back safely.
1. How to download and install WP-CLI
The official website
You can install it on your server via SSH in just a few steps:
# Download the file
curl -O https://raw.githubusercontent.com/wp-cli/builds/gh-pages/phar/wp-cli.phar
# Make it executable
chmod +x wp-cli.phar
# Move it to your global bin folder
sudo mv wp-cli.phar /usr/local/bin/wp
2. How to use it for domain migration
First, navigate to your WordPress root directory. Before making real changes, it is smart to run a simulation using the --dry-run flag to see what will change:
$ wp search-replace 'https://old-website.phpdev.top' 'https://new-website.top' --precise --dry-run
If you see the error like the next, you probably execute this command from the root, despite it is not recommended you can use the --allow-root flag to fix that
$ wp --allow-root search-replace 'https://old-website.phpdev.top' 'https://new-website.top' --precise --dry-run
The result will look like
$ wp search-replace 'https://old-website.phpdev.top' 'https://new-website.top' --precise --dry-run
+--------------+-----------------------+--------------+------+
| Table | Column | Replacements | Type |
+--------------+-----------------------+--------------+------+
| wp_comments | comment_author_url | 149 | PHP |
| wp_comments | comment_content | 22 | PHP |
| wp_postmeta | meta_value | 683 | PHP |
| wp_posts | post_content | 3816 | PHP |
| wp_posts | guid | 341 | PHP |
+--------------+-----------------------+--------------+------+
Success: 5018 replacements to be made.
If everything looks good, run the actual command to update the whole database safely:
$ wp search-replace 'https://old-website.phpdev.top' 'https://new-website.top' --precise
Using WP-CLI saves a lot of time and keeps your WordPress data completely safe!