Paulund
2013-05-16 #wordpress

Multi Environment WordPress wp-config.php

When you are developing any website you will always have different environments for your website, the number of environments you need will depend on the size of the project and how many people are involved in the project. The main environments you will find in any website project are:

  • Development Server - The developers local machine to development the website.
  • Testing Server - Once development is finished this will be where all testing takes place.
  • User Acceptance Testing Server - Where the client will review the changes to the website.
  • Production Server - The live website.

The two environments you will always need to have is a development environment and a production environment. You will normally only have these two environments if the client doesn't need to view the site before it goes live. This means that once the developer has finished working on the site they can simply put this onto the production server. These are normally for the very basic of projects where the developer can simply test on their local development server before going live. If you have a client that needs to review your development before the site goes live then you have a user acceptance testing server (UAT server), this environment should match the production server as close as possible. When the developer has finished testing locally then they can upload the site to the UAT server for the client to review. Once the user has accepted the changes made by the developer then the site can be moved to the production site. For multiple developer projects there will be a need for you to have an additional testing server inbetween development and UAT. You need this server because as the developer is creating the website and checking in the code to source control they will only be testing on their own environment, over time this environment could become out of step with the other developers environments. Once the developer has checked in their code to source control they should then deploy this to the testing server. This is where all the developers will push their changes so it can be tested with all the other developer changes. Once this server is stable and has past testing then you can push these changes to the UAT server, where the client will review these changes and if accepted will be pushed to the production server.

Multi Environment With WordPress

If you have a WordPress project then you want to make it easy to switch between different environments, the easiest way is to allow you to upload everything to do with your project to the server. This will mean that all the changes you make will be uploaded not just the changes to your plugins or themes. But if you upload everything you will also upload the wp-config.php file, this file will tell WordPress how to connect to the underlining database. The wp-config.php file is just a PHP file so you can change it to get the credentials for the database depending on what server it is being served from, simply by using the $_SERVER global variable to differ the environments. The variables you need to change between environments are:

  • DB_NAME - Name of the database

  • DB_USER - User to connect to the database

  • DB_PASSWORD - Password to conenct to the database

  • DB_HOST - The host name of the database

  • WP_HOME - The location of the WordPress Home URL

  • WP_SITEURL - The location of the WordPress Site URL, most of the time for will be the same as WP_HOME depending on if WordPress is installed in a sub-directory.

  • WP_DEBUG - To display an PHP errors or warnings.

  • WP_CACHE - To cache the WordPress output.


<?php

if( stristr( $_SERVER['SERVER_NAME'], "dev" ) ) {
 
 	// Dev Environment
	define( 'DB_NAME', 'project_dev' );
	define( 'DB_USER', 'project_dev_user' );
	define( 'DB_PASSWORD', 'password' );
	define( 'DB_HOST', 'localhost' );
	
	define( 'WP_HOME', 'http://project.dev');
	define( 'WP_SITEURL', WP_HOME);
	
	// Dev will always want debug on and caching off
	define( 'WP_DEBUG', true );
	define( 'WP_CACHE', false );
	 
} elseif( stristr( $_SERVER['SERVER_NAME'], "test" ) ) {
 
	// Test Environment
	define( 'DB_NAME', 'project_test' );
	define( 'DB_USER', 'project_test_user' );
	define( 'DB_PASSWORD', 'password' );
	define( 'DB_HOST', 'localhost' );
	
	define( 'WP_HOME', 'http://project.test'); 
	define( 'WP_SITEURL', WP_HOME);
	
	// Testing will always want debug on and caching off
	define( 'WP_DEBUG', true);
	define( 'WP_CACHE', false);
	
} elseif( stristr( $_SERVER['SERVER_NAME'], "uat" ) ) {
 
	// UAT Environment
	define( 'DB_NAME', 'project_uat' );
	define( 'DB_USER', 'project_uat_user' );
	define( 'DB_PASSWORD', 'password' );
	define( 'DB_HOST', 'localhost' );
	
	define( 'WP_HOME', 'http://project.uat'); 
	define( 'WP_SITEURL', WP_HOME);
	
	// UAT Environment will always be the same as production so turn off debug and turn on caching
	define( 'WP_DEBUG', false );
	define( 'WP_CACHE', true );	
	 
} else {
 
	// Production Environment
	define( 'DB_NAME', 'project_live' );
	define( 'DB_USER', 'project_live_user' );
	define( 'DB_PASSWORD', 'password' );
	define( 'DB_HOST', 'localhost' );
	
	define( 'WP_HOME', 'http://project.com'); 
	define( 'WP_SITEURL', WP_HOME); 
	
	// Live Environment will always be the same as production so turn off debug and turn on caching
	define( 'WP_DEBUG', false );
	define( 'WP_CACHE', true );
		
}
 
define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');
?>

Using DotEnv

As you can see that having all your server settings in one files can be dangerous if someone manages to get their hands on this file, they will be able to get full access to all your different environments. A good way to solve this problem would be to use a PHP library called dotenv, this library allows you to separate your config files into environment files and will load these variables into your config file depending on the server it is ran on.


$root_dir = __DIR__;

if (file_exists($root_dir . '/.env')) {
    Dotenv::load($root_dir, '.env');
}

/**
 * Define required environment settings
 */
Dotenv::required(array('DB_NAME', 'DB_USER', 'DB_PASSWORD', 'WP_HOME', 'WP_SITEURL'));

/**
 * Database
 */
define( "DB_NAME", getenv("DB_NAME") );
define( "DB_USER", getenv("DB_USER") );
define( "DB_PASSWORD", getenv("DB_PASSWORD") );
define( "DB_HOST", getenv("DB_HOST") );

/**
 * URLs
 */
define( "WP_HOME", getenv("WP_HOME") );
define( "WP_SITEURL", getenv("WP_SITEURL") );

Have a look at using DotEnv on your next project. DotEnv