WordPress Configuration Tricks
Many WordPress users know the wp-config.php
file as the key to the WordPress database. It is where you set the database name, username, password, and location (among other things like security keys, database prefix, and localized language).
Here’s a screenshot of wp-config.php
(aka the WordPress configuration file) for those who may not yet be familiar:
But what many users don’t know is that the wp-config.php
file may be used to specify a wide variety of configurational settings, enabling you to improve the functionality, performance, and security of your WordPress-powered site. In this article, I share as many of these configurational tricks as I have been able to collect over the years. This guide covers everything in the WordPress Codex, as well some additional tricks that you probably haven’t seen before. If you know of any other WordPress configuration tricks, share them in the comments and I will add them to the post.
Database Credentials *
This set of four configurational definitions are required for WordPress to connect to the database:
define('DB_NAME', 'database-name');
define('DB_USER', 'database-username');
define('DB_PASSWORD', 'database-password');
define('DB_HOST', 'localhost');
Database name, username, and password should be readily available to you during database creation, but the DB_HOST
value may be more difficult to acquire. Most commonly, this value is simply “localhost
”, but if that doesn’t work, here are a few other values to try:
- 1and1 Hosting —
db12345678
- DreamHost —
mysql.example.com
- GoDaddy —
h41mysql52.secureserver.net
- ICDSoft —
localhost:/tmp/mysql5.sock
- MediaTemple (GS) —
internal-db.s44441.gridserver.com
- Pair Networks —
dbnnnx.pair.com
- Yahoo —
mysql
You can even specify an alternate port for your database server. Here are two examples:
define('DB_HOST', 'localhost:1234');
define('DB_HOST', 'mysql.domain.tld:1234');
Another cool trick is to detect the database server value automatically:
define('DB_HOST', $_ENV{DATABASE_SERVER});
If all of these fail, or if you are still having problems, consult your hosting provider for assistance.
Database Character Set and Collation *
As of WordPress version 2.2, you may specify a character set for your MySQL database tables. Generally, there is no reason to change the default character-set value of UTF-8, which is usually perfect because it supports all languages. Here is the default (and recommended) setting:
define('DB_CHARSET', 'utf8');
WordPress version 2.2 also enables you to specify the collation, which is the sort order of your database character set. Setting the collation is generally handled automatically by MySQL according to the character set, which is enabled by leaving the collation value blank as done in the default setting for this definition. Here is the default (and recommended) setting:
define('DB_COLLATE', '');
wp-config.php
file.Security Keys *
As of WordPress 2.7, there are four security keys available that are designed to insure better cookie encryption. These keys work silently in the background and should be as random and complicated as possible (no, you will never need to remember them). The easiest way to generate these keys is to do it automatically at the WordPress.org secret-key service. Simply visit that link and copy/paste the results into your wp-config.php
file. Note that these keys may be changed anytime, and doing so will invalidate all of your users’ existing cookies so that they will have to re-login to your site.
define('AUTH_KEY', ':dr+%/5V4sAUG-gg%aS*v;&xGhd%{YV)p:Qi?jXLq,<h\\`39');
define('SECURE_AUTH_KEY', '@*+S=8\"\'+\"}]<m#+}V)p:Qi?jXLq,<h\\`39m_(');
define('LOGGED_IN_KEY', 'S~AACm4h1;T^\"qW3_8Zv!Ji=y|)~5i63JI |Al[(<YS');
define('NONCE_KEY', 'k1+EOc-&w?hG8j84>6L9v\"6C89NH?ui{*3\\(t09mumL/fF');
Database Prefix *
The database prefix setting is particularly useful for increasing the security of your site and for housing multiple WordPress installations in a single database. By changing the default value of “wp_
” to something randomly unique, you mitigate commonly targeted attack vectors and improve the overall security of your site. Here is the default setting:
$table_prefix = 'wp_';
There are tons of crackers out there probing sites for this default database prefix. Changing it to something like “x777_” is a good way to avoid these types of targeted attacks.
You can also use this setting to install multiple instances of WordPress using the same database. Simply specify a unique database prefix for each installation:
$table_prefix = 'wp1_'; // first blog
$table_prefix = 'wp2_'; // second blog
$table_prefix = 'wp3_'; // third blog
Language Settings *
WordPress makes it possible to specify a language-translation file and its associated directory. The language translation file is assumed to be of the “.mo
” variety, and its default location (if no explicit path is specified) is assumed to be wp-content/languages
(first) and then wp-includes/languages
(second). Here is the default setting:
define('WPLANG', '');
define('LANGDIR', '');
Directory Settings *
Technically not something that you should need to mess with, the default wp-config.php
file contains a few lines that specify the absolute path and include the settings file. I include them here for the sake of completeness:
/** WordPress absolute path to the WordPress directory. */
if ( !defined('ABSPATH') )
define('ABSPATH', dirname(__FILE__) . '/');
/** Sets up WordPress vars and included files. */
require_once(ABSPATH . 'wp-settings.php');
Blog Address and Site Address
Now we’re getting to some of the cool stuff. By default, these two configurational definitions are not included in the wp-config.php
file, but they should be added to improve performance. These two settings were introduced in WordPress version 2.2 and override the database value without actually changing them.
Adding these two definitions in your site’s wp-config.php
file reduces the number of database queries and thus improves site performance. These settings should match those specified in your WordPress Admin. Here is an example (note that you should not include a trailing slash at the end of either URL):
define('WP_HOME', 'https://digwp.com');
define('WP_SITEURL', 'https://digwp.com');
A cool trick is to set these values dynamically by grabbing the global server variable:
define('WP_HOME', 'http://'.$_SERVER['HTTP_HOST'].'/path/to/wordpress');
define('WP_SITEURL', 'http://'.$_SERVER['HTTP_HOST'].'/path/to/wordpress');
Probably best to escape those values if using on a public site.
Template Path and Stylesheet Path
As with the predefined constants for blog address and site address (see previous section), you can also boost performance by eliminating database queries for the template path and stylesheet path for your site. Here are the default values for these two definitions:
define('TEMPLATEPATH', get_template_directory());
define('STYLESHEETPATH', get_stylesheet_directory());
As is, these two definitions are still querying the database, but we can eliminate these extraneous queries by hardcoding the values into place:
define('TEMPLATEPATH', '/absolute/path/to/wp-content/themes/active-theme');
define('STYLESHEETPATH', '/absolute/path/to/wp-content/themes/active-theme');
Disable Cache and Cache Expiration
These two options apply to older versions of WordPress that are still using the default object-based caching mechanism. The first definition enables you to enable or disable the cache, while the second definition enables you to specify the cache expiration time.
Enable the cache
define('WP_CACHE', true); // enable the cache
define('ENABLE_CACHE', true); // enable the cache
define('CACHE_EXPIRATION_TIME', 3600); // in seconds
Disable the cache
define('WP_CACHE', false); // disable the cache
define('DISABLE_CACHE', true); // disable the cache
Specify Cookie Domain
There are several reasons why you want to specify a cookie domain for your site. A common example involves preventing cookies from being sent with requests for static content on subdomains. In this case, you would use this definition to tell WordPress to send cookies only to your non-static domain. This could be a significant performance boost. Here are some examples of setting various cookie path and cookie domain information:
define('COOKIE_DOMAIN', '.digwp.com'); // don't omit the leading '.'
define('COOKIEPATH', preg_replace('|https?://[^/]+|i', '', get_option('home').'/'));
define('SITECOOKIEPATH', preg_replace('|https?://[^/]+|i', '', get_option('siteurl').'/'));
define('PLUGINS_COOKIE_PATH', preg_replace('|https?://[^/]+|i', '', WP_PLUGIN_URL));
define('ADMIN_COOKIE_PATH', SITECOOKIEPATH.'wp-admin');
Override File Permissions
If your web host’s default file permissions are too restrictive, adding these definitions to your WordPress configuration file may help resolve the issue. Note that you don’t need the quotes around the permission values. For example:
define('FS_CHMOD_FILE', 0755);
define('FS_CHMOD_DIR', 0755);
View All Defined Constants
Need to view all predefined constants? Good news, this PHP function will return an array of all currently defined constants:
print_r(@get_defined_constants());
Custom User and Usermeta Tables
What about custom user and usermeta tables? Yep, you can do that too, with the following definitions:
define('CUSTOM_USER_TABLE', $table_prefix.'my_users');
define('CUSTOM_USER_META_TABLE', $table_prefix.'my_usermeta');
FTP/SSH Constants
This set of configurational definitions is designed to help users locate and utilize FTP/SSH connections. Here is a example set of predefined constants for FTP/SSH updates:
define('FS_METHOD', 'ftpext'); // forces the filesystem method: "direct", "ssh", "ftpext", or "ftpsockets"
define('FTP_BASE', '/path/to/wordpress/'); // absolute path to root installation directory
define('FTP_CONTENT_DIR', '/path/to/wordpress/wp-content/'); // absolute path to "wp-content" directory
define('FTP_PLUGIN_DIR ', '/path/to/wordpress/wp-content/plugins/'); // absolute path to "wp-plugins" directory
define('FTP_PUBKEY', '/home/username/.ssh/id_rsa.pub'); // absolute path to your SSH public key
define('FTP_PRIVKEY', '/home/username/.ssh/id_rsa'); // absolute path to your SSH private key
define('FTP_USER', 'username'); // either your FTP or SSH username
define('FTP_PASS', 'password'); // password for FTP_USER username
define('FTP_HOST', 'ftp.domain.tld:21'); // hostname:port combo for your SSH/FTP server
Moving Your wp-content directory
As of WordPress version 2.6, you may change the default location of the wp-content
directory. There are several good reasons for doing this, including enhancement of site security and facilitation of FTP updates. Some examples:
// full local path of current directory (no trailing slash)
define('WP_CONTENT_DIR', $_SERVER['DOCUMENT_ROOT'].'/path/wp-content');
// full URI of current directory (no trailing slash)
define('WP_CONTENT_URL', 'http://domain.tld/path/wp-content');
You may also further specify a custom path for your plugins
directory. This may help with compatibility issues with certain plugins:
// full local path of current directory (no trailing slash)
define('WP_PLUGIN_DIR', $_SERVER['DOCUMENT_ROOT'].'/path/wp-content/plugins');
// full URI of current directory (no trailing slash)
define('WP_PLUGIN_URL', 'http://domain.tld/path/wp-content/plugins');
Dealing with Post Revisions
Recent versions of WordPress provides a post-revisioning system that enables users to save different versions of their blog posts and even revert to previously saved versions if necessary. Regardless of how much you do or do not despise this amazingly awesome feature, here are a couple of configurational definitions that may prove useful for you ;)
Limit the number of saved revisions
define('WP_POST_REVISIONS', 3); // any integer, but don't get too crazy
Disable the post-revisioning feature
define('WP_POST_REVISIONS', false);
Specify the Autosave Interval
In a similar vein as the post-revisioning feature is WordPress’ actually useful Autosave functionality. By default, WordPress saves your work every 60 seconds, but you can totally modify this setting to whatever you want. Don’t get too crazy though, unless you want to stress-out your server ;)
define('AUTOSAVE_INTERVAL', 160); // in seconds
Debugging WordPress
Since WordPress version 2.3.1, users have been able to display certain errors and warnings to help with the debugging of their site. As of WordPress version 2.5, enabling error reporting raises the reporting level to E_ALL
and activates warnings for deprecated functions. By default (i.e., if no definition is specified in the wp-config.php
file), error reporting is disabled.
define('WP_DEBUG', true); // enable debugging mode
define('WP_DEBUG', false); // disable debugging mode (default)
Error Log Configuration
Here is an easy way to enable basic error logging for your WordPress-powered site. Create a file called “php_error.log
”, make it server-writable, and place it in the directory of your choice. Then edit the path in the third line of the following code and place into your wp-config.php
file:
@ini_set('log_errors','On');
@ini_set('display_errors','Off');
@ini_set('error_log','/home/path/domain/logs/php_error.log');
Increase PHP Memory
If you are receiving error messages telling you that your “Allowed memory size of xxx bytes exhausted,” this setting may help resolve the issue. AS of WordPress version 2.5, the WP_MEMORY_LIMIT
definition enables you to specify the maximum amount of memory that may be used by PHP. By default, WordPress will automatically attempt to increase PHP memory up to 32MB, so this setting is only needed for values higher than 32MB. Note that some web hosts disable your ability to increase PHP memory, so you may need to beg for them to do it. Here are some examples:
define('WP_MEMORY_LIMIT', '64M');
define('WP_MEMORY_LIMIT', '96M');
define('WP_MEMORY_LIMIT', '128M');
Save and Display Database Queries for Analysis
This technique is perfect for saving database queries and displaying the information for subsequent analysis. The process saves each query, its associated function, and its total execution time. This information is saved as an array and may be displayed on any theme template page. To do this, first add the following directive to your wp-config.php
file:
define('SAVEQUERIES', true);
Then, in the footer of your active theme, place the following code:
// display the query array for admin only
if (current_user_can('level_10')) {
global $wpdb;
echo "<pre>";
print_r($wpdb->queries);
echo "</pre>";
}
Here is a single-line version of this function:
<?php if (current_user_can('level_10')) { global $wpdb; echo "<pre>"; print_r($wpdb->queries); echo "</pre>"; } ?>
Control Proxy Access
Since WordPress 2.8, the configuration file may be used to define constants involved with blocking, allowing and filtering access to specific hosts from behind a proxy server. For example, if you host your WordPress site on an intranet network, you may prevent access to all external hosts and only allow requests from localhost and your blog using the first definition below. You may also allow specific hosts access with a comma-separated list of allowed hostnames, as demonstrated in the third definition below.
define('WP_HTTP_BLOCK_EXTERNAL', true); // block external requests
define('WP_HTTP_BLOCK_EXTERNAL', false); // allow external requests
define('WP_ACCESSIBLE_HOSTS', 'api.wordpress.org'); // whitelist hosts
api.wordpress.org
access to ensure proper functionality of core files and plugins.Whew! I’m wiped. Time for a little break :)
Notes
- * Denotes that code is included in the default
wp-config.php
file - Brazilian Portuguese translation (by Tárcio Zemel)
62 responses
-
Excellent article, Jeff.
By default, config files are not viewable, but for added security, you could always move your config file to a new directory, just to make your default WP install a little more secure.
Also, a lot of people have been having issues with strange symbols appearing in their posts. For example, an apostrophe will change to some strange symbol.
Many people have had success in fixing the issue by changing their encoding from utf8 to latin1 (and visa versa).
-
I’ll have to give that encoding trick a go…only on WordPress MU do I get an issue where if I name my blog something like “Jason’s Blog” with that apostrophe, it get’s escaped multiple times and I can see the backslash. This only happens for certain tags, like the bloginfo tag in the footer, I’ll get Jason’s blog.
-
-
Thanks Jeff, loads of cool config options for the WP newbie like me.
-
Nice job! Thank you very much!
-
Wow! HUGE list! Thanks for sharing.
-
Very neat list
You missed a few cool stuff regarding WP_HTTP class, that allows proxy config (cool if you’re installing WP behind a corporate firewall for example)
Oh, last thing, your <pre> could have overflow:auto; to make long lines readable ;)
-
Excellent info on the WP config file just what I was looking for as I embark on 6 new wp installs…
-
If those six installs are going to be on the same server, you can save a lot of time and future maintenance headaches by editing your config.php to handle multiple websites on only a single installation of WordPress.
-
-
in moving my wp-content directory, the images i uploaded using the default wp image uploader no longer show up. do you have any idea what the problem may be? i already checked the codex, to no avail.
-
Chris: I believe image URLs are saved in the database with the full URL. You can go into the DB and do a search/replace – oldURL/newURL.
-
i just tried your suggestion and it didn’t work. perhaps i went about it wrong?
i downloaded a backup of the database from the cPanel,
did a find/replace of domain.com/wp-content replaced with domain.com/secretFolderName/wp-content,
then i restored that database using the cPanel.
-
-
-
Excellent post! I already implement “Blog Address and Site Address” “Revisions” and the “auto-save”limiter.
Thanks!
-
Excellent article! Regards from Brazil.
-
Great list, I can’t believed I missed out so much.
Just a little doubt on the note of security keys. Since WP 2.5, secret keys could be generated using the secret key API v1.0. I noticed in v1.1, it is no longer just 1 variable but 4.
Has the constant (SECRET_KEY) been discontinued?
-
Thanks for the info, I never knew that there were so many Security Keys. I have just updated my config file.
-
Great post! I’m especially looking forward to try out the various settings for cookies, to see if I can can get, as you put it, a significant performance boost :)
-
Really awesome article. This site is proving to have a lot of useful information on it. And I had no idea that all this could be done, I’d never seen that codex page before!
-
Cant thank you enough for writing this amazing article.
I got little bored while reading first few configuration explanation but the latter part is damn good.
Cool stuff overall !!
-
Great post guys. Some things I never knew in there.
-
Don’t define TEMPLATEPATH and SYLESHEETPATH if you have installed plugin for mobile (iPhone) template.
-
Hello Jeff _
The possibilities to customize Word press seem endless and the best part is that a wide variety of these options can be self taught with the help of excellent post like this one. This is very useful and actionable information.
Thank you!
-
There are a few more definitions in regards to the security keys:
define('AUTH_SALT', 'Insert');
define('SECURE_AUTH_SALT', 'Insert');
define('LOGGED_IN_SALT', 'Insert');
define('NONCE_SALT', 'Insert');
You can use the same service as for the KEYS to generate the random data. These are used in conjunction with the keys for encryption. If they don’t exist WordPress will query the database for a value. If the value doesn’t exists in the database a key will be generated and stored in the database.
-
Awesome post — really appreciate it. I implemented a few of these — but had issues with the cookie settings — probably because the blog is in a directory — so is the cookie domain just the main domain?
-
I decided to try a few of these things for a new site I’m building. Specifically, the URL/HOME ones seemed very useful so I wouldn’t have to go digging through the database when I moved the site to a live server. However, this bit blew things up with no errors.
define('TEMPLATEPATH', '/absolute/path/to/wp-content/themes/active-theme');
All I got was a blank white screen with no code at all for every post/page I tried to view that wasn’t home. I thought maybe I’d messed something up with the theme while developing it, so I tried checking out the default one and others and got the same problem.
Took me 45 minutes to figure out WTF was going on. I commented out each define I’d put in the config until things started working again. For some reason it hates if I use a define called TEMPLATEPATH.
-
Got the same issue with TEMPLATEPATH (or maybe STYLESHEETPATH). Didn’t take me 45 minutes but still no idea what’s going on.
-
-
Nice post :)
-
Hi, and welcome to the “WordPress Blogging Sphere” :-) Great posts you guys have started out with, curious to read whatever you come up with next.
-
After I defined
'WP_HOME'
'WP_SITEURL'
and
'TEMPLATEPATH'
'STYLESHEETPATH',
I immediattle boost my website speed from 1.2 sec to 0.7 sec. Thanks for tips.
-
Thanks as these are great. Weird thing is that I added define(‘WP_POST_REVISIONS’, 3);
and it doesnt seem to be working. I have 2.8. I just add this into wp-config, correct?
-
Thanks for a gentle introduction to the wp-config.php.
I only knew about the usual bits and pieces that you have to fill in but this info has given me a lot more info.
-
Wow it is more than enough to understand your visions from your introduction :) I am sure that this info will help me a lo in the future :)
-
Just wondering if anyone saw my question here? I added your suggestions, including
define('WP_POST_REVISIONS', 3);
in my wp-config, just before the final
?>
However, the post revisions is not working at all in that new articles created since have many more revisions. So, I am curious if there is something that I am missing or if I did something wrong. Any ideas.
Help would be greatly appreciated. Thanks folks.
-
Thanks for the tips. I realize you cant help specifically but wanted to make sure that this was still supposed to work. Not sure what might be going on. Bummer. But, thanks.
PS – am running 2.8, quadruple checked syntax, might be a plugin issue, haven’t tried another install….
Thanks again.
-
PS – very cool, I didnt see the book before.
-
Many thanks for this great article.
I write from germany an have a small question about your (dropping) Code-Boxes with that mouse-over effect (as showed in the article). How do you realize that? I searched through you blog but didn’t find anything – maybe you hav a tip? Sorry for my bad english and thank you in advance.
-
WOW… it is a significant boost in loading time. I implemented WP_HOME, WP_SITEURL, TEMPLATEPATH, STYLESHEETPATH, all COOKIE definitions, disabled WP_POST_REVISIONS and set AUTOSAVE_INTERVAL to 160 sec.
Thanks a bunch for this post!
-
I think Chris posted something on that just a few days ago
Thank you very much :-)
-
I don’t understand the “Specify Cookie Domain” Code, can give me someone a working example?
Thanks & Best, Panzz
-
what’s the point of moving the wp-content folder if someone can just look in your header for a link to your stylesheet?
-
How you manage to digg so deep and write such excellent stuff….I am managing several sites and all are in wordpress….I think these tips and tweaks will really help…
Thanks for this
-
i like this site. i added on my bookmark i thanks
-
Beware of the WordPress.org secret key service. Codes with an apostrophe or double apostrophe create a Parse error: syntax error, unexpected T_STRING
-
Good Job,thanks for share.. :D :D visit my Blog Ya :P
-
Very useful tips.. thank you…
-
Wow… The power of Digwp is endless. Thanks a lot Jeff and I’m waiting nervous book release. :)
-
Great break down of tricks!
I recently moved my website and everything is working out under the new domain name except for the search—the URL is still showing the old server. Any ideas on how to change this? I have the new URL defined in the wp-config file. And if I change the URL to the new domain name, the search does still work, but it’s just not set to the default search…
Thanks!
-
Hi, one thing which i searched and couldnt find so i made myself one (not the best in the world at php so it might not be the best way to do it but what i wanted to do for the company i work for, was make a new intranet, one which from inside the company, had unrestricted access, but from outside the companys network, i wanted only users who had registered to be able to get in, and i couldnt find anywhere how to do this so i thought i might post here how i did it just incase someone else is struggling to do it, but as i can see not many people search it haha anyway the link is here
My code in pastebinHope it helps someone