In this post, we’ll look at how to transfer a single serialized option between WordPress installations from the command line. This technique can be usefull when dealing with serialized data that include PHP class objects. If you just want to copy all options, this is not the post you are looking for.
The Problem with Serialized Options in WordPress
WordPress has a robust system for storing and retrieving data through its options system. While simple data types (like integers and strings) are straightforward, WordPress automatically serializes complex data types—like arrays and PHP objects—when they are stored in the options table. This process translates the data into a string representation that can be stored efficiently in the database. However, when it comes to transferring or moving this data between different WordPress installations, this serialized format presents a unique challenge.
The common WP-CLI commands used to interact with options — wp option get
and wp option update
— don’t natively support the transfer of serialized data. These commands support exporting and importing data in several formats like JSON
, YAML
, and VAR_EXPORT
Both JSON
and YAML
formats cannot preserve serialized PHP class objects during the transfer, and wp option update doesn’t support importing VAR_EXPORT
data turning it back into serialised data. Even importing a serialised string will cause issues as the data is escaped.
To address this problem, users have suggested adding a raw format option to wp option g
et. This suggestion was discussed in a GitHub issue. Until such an enhancement is introduced, developers need a workaround to transfer serialized data while maintaining its integrity.
Why Not Use var_export and eval?
It might seem tempting to utilize the var_export
format to get a parsable string representation of an option and then use eval
to restore it in the destination site. However we’ll pass on this primarily for security reasons. Instead, we will use serialize the data, encode it in base64 and then send it over.
Scenario:
We have two WordPress installations on the same server. We’re going to transfer a serialized option from the source installation to the destination installation.
The source WordPress installation is located at /var/www/source-wp-install/
and the destination WordPress installation at /var/www/dest-wp-install/
.
Let’s start by navigating to the source WordPress installation directory:
cd /var/www/source-wp-install/
Code language: Bash (bash)
Short Version:
Here’s a single command to transfer the option:
wp eval "echo base64_encode(serialize(get_option('your_option_name')));" | wp --path=/var/www/dest-wp-install/ eval "update_option('your_option_name', unserialize(base64_decode(fgets(STDIN))));"
Code language: Bash (bash)
And we’re done!
Long Version:
First, we retrieve and base64 encode the serialized option:
wp eval "echo base64_encode(serialize(get_option('your_option_name')));"
Code language: Bash (bash)
This command will output the base64 encoded serialized option. Keep this output handy for the next step.
Now, let’s update the option on the destination WordPress installation:
...output from previous command... | wp --path=/var/www/dest-wp-install/ eval "update_option('your_option_name', unserialize(base64_decode(fgets(STDIN))));"
Code language: Bash (bash)
And that’s it! You’ve successfully transferred a serialized option between WordPress installations using WP-CLI.
Accessing Remote Sites Using SSH
This technique is also beneficial when you need to retrieve an option from a remote site. With SSH access, you can execute the same commands on a remote server.
Navigate to your remote site’s directory and retrieve the serialized option or do it in one move using --path
if possible, and then import it to your local WordPress installation:
ssh [email protected] "wp --path=/path/to/your/wp/install/ eval \"echo base64_encode(serialize(get_option('your_option_name')));\"" | wp --path=/var/www/your-local-wp-install/ eval "update_option('your_option_name', unserialize(base64_decode(fgets(STDIN))));"
Code language: Bash (bash)
Remember to replace username
, your-server.com
, /path/to/your/wp/install/
, /var/www/your-local-wp-install/
, and your_option_name
with your actual details.