Quick Tip: Transferring a Serialized Option in WordPress Using WP-CLI

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 get. 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.

I'm a webdeveloper based in Oslo, Norway. I currently work with web development at Nettmaker.

I would like to change the world, but they won't give me the source…

0 0 votes
Article Rating
Subscribe
Notify of
guest

0 Comments
Most Voted
Newest Oldest
Inline Feedbacks
View all comments