Portable Wordpress configuration

One of the problems commonly faced by webmasters using third-party content management systems is that it can be difficult to keep development and production copies in sync. Version control systems like Subversion or git can help with the files, but databases are often much trickier. If your CMS stores the filesystem path or URL in the database, you’re going to run into trouble when you try to move your development copy to the live server; your URLs, and possibly filesytem paths, are going to be wrong.

Wordpress makes it easy to avoid this problem.

A note about terminology

In this, as well as all my tutorials, I use the domain name example.org to refer to your domain. When you see this, substitute your actual domain name. As well, in this article I will assume you have installed Wordpress into a directory called /wordpress. If you use a different name for your Wordpress folder, just replace “wordpress” in any paths below with whatever name you chose.

Filesystem paths

First, Wordpress never stores a filesystem path anywhere. It detects it on-the-fly and stores the result in the ABSPATH constant. This ensures that the application will work properly no matter where it’s moved to. So there’s nothing to worry about here.

What about URLs?

URLs, however, are stored in two places. Because Wordpress allows you to install the application in one place and display the content in another, it needs to be aware of two URLs, one for the application and one for the site. These are stored in the database, in the options table, with the names siteurl and home. The first is the URL of the Wordpress application itself, and the second is the URL of the site. In many cases these values will be identical, but they may differ, as shown here:

mysql> SELECT option_name,option_value FROM wp_options WHERE option_name = "siteurl";
+-------------+----------------------------------+
| option_name | option_value                     |
+-------------+----------------------------------+
| siteurl     | http://www.example.org/wordpress | 
+-------------+----------------------------------+
 
mysql> SELECT option_name,option_value FROM wp_options WHERE option_name = "home";
+-------------+------------------------+
| option_name | option_value           |
+-------------+------------------------+
| home        | http://www.example.org | 
+-------------+------------------------+

Once upon a time we had to modify the database dump before importing it into production in order to change these values. This was error-prone and a hassle, making it a pain to move database contents back and forth between environments. Not a huge problem, but an annoyance nonetheless.

Not very elegant, is it?

In May 2007, Wordpress 2.2 was released which introduced the ability to set your site address and blog address via constants in wp-config.php. This was great news for anyone developing with Wordpress on one server and deploying on another, as it eliminated the need to edit the database to update hostnames, as described above. So now, instead of having to edit the database contents, you can simply define these two constants in your wp-config.php file and take advantage of PHP to set the values based on whatever criteria you like.

When customizing wp-config.php, some people wrap these constants in tests that set the URLs to various values depending on other conditions. Others will check the hostname contained in PHP’s $_SERVER['HTTP_HOST'] superglobal variable and set the correct names for their different environments accordingly. I like to go one step further and assign the value of $_SERVER['HTTP_HOST'] directly:

// ** Hostname settings ** //
define('WP_SITEURL', "http://${_SERVER['HTTP_HOST']}/wordpress");
define('WP_HOME',    "http://${_SERVER['HTTP_HOST']}");

The path in the first line, WP_SITEURL, should be adjusted to where ever you have Wordpress installed. If Wordpress is installed in your site’s root directory, both lines should be identical; if Wordpress is installed in a folder called “blog”, the first line should use that instead of “wordpress”, which I’ve used here. These values will override anything stored in your database, so you can even add them to an existing site without worrying about how they’re set currently.

The end result of this custom configuration file is that your database can now be copied back and forth between servers with impunity, and you can be sure it will always work. You can now grab a fresh copy of your live data when working locally and import modified data to production as needed (but watch out for any new comments posted between the time of your last copy and the time you reload it).

This is old news for a lot of people — we’ve been able to do this for over a year, after all — but I’ve found that many people still aren’t aware of it. All the Wordpress 2.2 release notes have to say on the subject is “You can also hardcode your site and WP URL in the config file, overriding the values in the DB”, which is not a very good description of such a useful development feature, so I suspect a lot of people skimmed over it without realizing what it meant. My hope is to bring this information to more people who are still fighting with portability issues between servers, and hopefully inspire other web application developers to implement similar capabilities in their own software.