
Create a multi-environment WordPress Configuration in a few simple steps
While WordPress has evolved over time, the one constant is the ‘wp-config.php’ file… to some, it is a bear to manage, but if you take a little time and give it some much needed love and attention, you can use a single file across multiple environments…
Before we dive in too deep, I am going to drop a few reference links here so if you want more background on the wp-config file or WordPress Constants you can take a peek.
- WordPress Common API Handbook by WordPress.org
- WordPress Constants Overview by WP Engineer
- All Those Damned wp-config Constants by Mike Garrett
Lets take a look at the default file, as it ships with WordPress….
<?php
/**
* The base configuration for WordPress
*
* The wp-config.php creation script uses this file during the installation.
* You don't have to use the web site, you can copy this file to "wp-config.php"
* and fill in the values.
*
* This file contains the following configurations:
*
* * MySQL settings
* * Secret keys
* * Database table prefix
* * ABSPATH
*
* @link https://wordpress.org/support/article/editing-wp-config-php/
*
* @package WordPress
*/
// ** MySQL settings - You can get this info from your web host ** //
/** The name of the database for WordPress */
define( 'DB_NAME', 'database_name_here' );
/** MySQL database username */
define( 'DB_USER', 'username_here' );
/** MySQL database password */
define( 'DB_PASSWORD', 'password_here' );
/** MySQL hostname */
define( 'DB_HOST', 'localhost' );
/** Database charset to use in creating database tables. */
define( 'DB_CHARSET', 'utf8' );
/** The database collate type. Don't change this if in doubt. */
define( 'DB_COLLATE', '' );
/**#@+
* Authentication unique keys and salts.
*
* Change these to different unique phrases! You can generate these using
* the {@link https://api.wordpress.org/secret-key/1.1/salt/ WordPress.org secret-key service}.
*
* You can change these at any point in time to invalidate all existing cookies.
* This will force all users to have to log in again.
*
* @since 2.6.0
*/
define( 'AUTH_KEY', 'put your unique phrase here' );
define( 'SECURE_AUTH_KEY', 'put your unique phrase here' );
define( 'LOGGED_IN_KEY', 'put your unique phrase here' );
define( 'NONCE_KEY', 'put your unique phrase here' );
define( 'AUTH_SALT', 'put your unique phrase here' );
define( 'SECURE_AUTH_SALT', 'put your unique phrase here' );
define( 'LOGGED_IN_SALT', 'put your unique phrase here' );
define( 'NONCE_SALT', 'put your unique phrase here' );
/**#@-*/
/**
* WordPress database table prefix.
*
* You can have multiple installations in one database if you give each
* a unique prefix. Only numbers, letters, and underscores please!
*/
$table_prefix = 'wp_';
/**
* For developers: WordPress debugging mode.
*
* Change this to true to enable the display of notices during development.
* It is strongly recommended that plugin and theme developers use WP_DEBUG
* in their development environments.
*
* For information on other constants that can be used for debugging,
* visit the documentation.
*
* @link https://wordpress.org/support/article/debugging-in-wordpress/
*/
define( 'WP_DEBUG', false );
/* Add any custom values between this line and the "stop editing" line. */
/* That's all, stop editing! Happy publishing. */
/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', __DIR__ . '/' );
}
/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';
The core file has all the minimal configuration options required to get a site up and running (and I do mean A SITE, singular)… but it definitely leaves a bit to be desired for WordPress Power Users and Developers.
The process can be summarized using the following list
- First, you setup your Database Username, Password, Host and Name
- Second, you configure the security salts
- Third, set your Table prefix (if you want something other than ‘wp_’
- Lastly, turn on debugging
Now, lets make some changes to empower our configuration to work across all of our environments. In this example, I am going to leave the ‘sensitive’ information blank but I will discuss my reasoning for including specific WP CONSTANTS as we step through my re-factored wp-config file.
First, lets update our file header to provide a summary/overview of what’s going to happen.
<?php
/**
* Custom WordPress Configuration File
*
* This file contains the following configurations:
*
* * Default Constants
* * Determine Environment Type
* * Environment Specific Constants
* * ABSPATH
*
* @link https://wordpress.org/support/article/editing-wp-config-php/
*
* @package WordPress
*/
Second, lets define our NEW default constants that will carry over between environments
/* DEFAULT GLOBAL CONSTANTS */
/* CONSTANTS AND VARIABLES ABOUT OUR DB, TABLES and SALTS */
define( 'DB_CHARSET', 'utf8' );
define( 'DB_COLLATE', '' );
define( 'DB_HOST', 'localhost' );
// security salts
// @link https://api.wordpress.org/secret-key/1.1/salt/
define('AUTH_KEY', 'insert generated salt here');
define('SECURE_AUTH_KEY', 'insert generated salt here');
define('LOGGED_IN_KEY', 'insert generated salt here');
define('NONCE_KEY', 'insert generated salt here');
define('AUTH_SALT', 'insert generated salt here');
define('SECURE_AUTH_SALT', 'insert generated salt here');
define('LOGGED_IN_SALT', 'insert generated salt here');
define('NONCE_SALT', 'insert generated salt here');
/* END CONSTANTS AND VARIABLES ABOUT OUR DB, TABLES and SALTS */
// Move any of the below CONSTANTS into the "DEFINE CONSTANTS BASED UPON ENVIRONMENT" section if they need to be independantly configured
/* WORDPRESS DEFAULT SETTINGS OVERRIDES */
define( 'AUTOSAVE_INTERVAL', 300 ); // auto-save posts/pages every 5 minutes (Default: 60)
define( 'EMPTY_TRASH_DAYS', 7 ); // Number of days between deleting posts/pages marked as Trash (Default: 30)
define( 'DISALLOW_FILE_EDIT', true ); // Disable the WP Theme & Plugin Editor
define( 'WP_AUTO_UPDATE_CORE', 'minor' ); // OPTIONS: true -> enabled, false -> disabled, minor -> only minor versions
define( 'WP_MEMORY_LIMIT', '256M' ); // Front-End Memory Limit
define( 'WP_MAX_MEMORY_LIMIT', '512M' ); // Admin Memory Limit
define( 'WP_POST_REVISIONS', 3 ); // Limit the number of post revisions to keep (Default: true [unlimited])
/* WORDPRESS DEFAULT SETTINGS OVERRIDES */
/* GLOBAL SMTP MAIL SETTINGS */
define( 'SMTP_USER', 'enterEmailAddressHere' );
define( 'SMTP_PASS', 'enterSMTPpasswdHere' );
define( 'SMTP_HOST', 'enterEmailServerHere' );
define( 'SMTP_FROM', 'enterEmailAddressHere' );
define( 'SMTP_PORT', '465' ); //25, 465 or 587
define( 'SMTP_SECURE', 'ssl' ); //ssl or tls
define( 'SMTP_AUTH', true );
/* END GLOBAL SMTP MAIL SETTINGS */
/* END DEFAULT GLOBAL CONSTANTS */
// Default Table Prefix - fall back for if not changed within specific environemnt
$table_prefix = 'wp_';
Before moving on to step three, note the SMTP constants that I have defined… This will allow you to use your SMTP server for all WordPress generated Emails, providing you add some additional custom code into your Theme/Child Theme ‘functions.php’ or a custom ‘must use plugin’ (the later is my preferred method). I will link to a customized ‘Site Wide Must Use Plugin’ that I use for the majority of the sites I develop.
Third, Lets get the current Server/Domain Name and set the environment type… This is where you can get as specific as you want, depending on how you create your domain names… I have opted to show you a less complex example (using specific keywords and defaulting to a production environment)…
/* DETERMINE ENVIRONMENT TYPE FROM SERVERNAME */
switch( true ):
case ( false !== strpos( $_SERVER['SERVER_NAME'], '.local' ) ):
$site_env = 'local';
break;
case ( false !== strpos( $_SERVER['SERVER_NAME'], '.dev' ) ):
case ( false !== strpos( $_SERVER['SERVER_NAME'], 'dev.' ) ):
$site_env = 'development';
break;
case ( false !== strpos( $_SERVER['SERVER_NAME'], 'staging.' ) ):
case ( false !== strpos( $_SERVER['SERVER_NAME'], '.staging' ) ):
$site_env = 'staging';
break;
default:
$site_env = 'production';
endswitch;
define( 'WP_ENVIRONMENT_TYPE', $site_env );
/* END DETERMINE ENVIRONMENT TYPE FROM SERVERNAME */
As an alternative for the DEFAULT case, you could use the PHP die() function and return a message to check the configuration file (even fancier, include a custom HTML file then call the die() function) for any unmatched case statements preceding it.
default:
die( 'Could not determine environment from the server name ( ' . $_SERVER["SERVER_NAME"] . ' )... Check your "wp-config" file.' );
Finally, lets define environment specific CONSTANTS
/* DEFINE CONSTANTS BASED UPON ENVIRONMENT */
switch( WP_ENVIRONMENT_TYPE ):
case 'production':
define( 'DB_NAME', 'enterProdDBhere' );
define( 'DB_PASSWORD', 'enterProdPasswdHere' );
define( 'DB_USER', 'enterProdUsername' );
define( 'FS_METHOD', 'direct' );
define( 'FS_CHMOD_DIR', 0755 );
define( 'FS_CHMOD_FILE', 0644 );
define( 'WP_DEBUG', false );
define( 'WP_DEBUG_DISPLAY', false );
define( 'WP_DEBUG_LOG', false );
define( 'COMPRESS_CSS', true );
define( 'COMPRESS_SCRIPTS', true );
define( 'CONCATENATE_SCRIPTS', true );
define( 'ENFORCE_GZIP', true );
define( 'SMTP_NAME', 'C.P. Web Designs' );
define( 'SMTP_DEBUG', 0 );
$table_prefix = 'prod_';
break;
case 'staging':
define( 'DB_NAME', '' );
define( 'DB_PASSWORD', '' );
define( 'DB_USER', '' );
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_DISPLAY', false );
define( 'WP_DEBUG_LOG', true );
define( 'SMTP_NAME', 'C.P. Web Designs Staging' );
define( 'SMTP_DEBUG', 1 );
break;
default:
define( 'DB_NAME', '' );
define( 'DB_PASSWORD', '' );
define( 'DB_USER', '' );
define( 'WP_DEBUG', true );
define( 'WP_DEBUG_DISPLAY', true );
define( 'WP_DEBUG_LOG', true );
define( 'SCRIPT_DEBUG', true );
// define( 'SAVEQUERIES', true );
// define( 'COMPRESS_CSS', true );
// define( 'COMPRESS_SCRIPTS', true );
// define( 'CONCATENATE_SCRIPTS', true );
// define( 'ENFORCE_GZIP', true );
define( 'SMTP_NAME', 'C.P. Web Designs Development' );
define( 'SMTP_DEBUG', 2 );
endswitch;
/* END DEFINE CONSTANTS BASED UPON ENVIRONMENT */
If you are a SITEGROUND user, I have added a bonus to incorporate something from their auto-installer
define( 'SITEGROUND', true ); // place this within the environment that runs on siteground servers
/** Absolute path to the WordPress directory. */
if ( ! defined( 'ABSPATH' ) ) {
define( 'ABSPATH', __DIR__ . '/' );
}
/** Sets up WordPress vars and included files. */
require_once ABSPATH . 'wp-settings.php';
if( defined( 'SITEGROUND' ) && SITEGROUND ):
@include_once('/var/lib/sec/wp-settings.php'); // Added by SiteGround WordPress management system
endif;
As you can see, the wp-config file can become a very powerful tool for the webmaster with a little love and modification.
To get yourself a copy of this customized wp-config file, visit our GitHub repository.
Thank you for another magnificent post. The place else could anybody get that type of info in such an ideal manner of writing?
I have a presentation next week, and I am on the look for such info.
Feel free to visit my web-site – Aegean College