Settings.php For Multiple Environments

Note that placing settings.php files in source control is risky (your database settings are in there!)  You might want to upload them manually via SFTP or other method rather than storing in your repository.

This is a follow-up article on the Knowledge Base article about using GIT on A Small Orange.  At this point, you should be able to get your code to the different repositories.  However, in order for this to really work, you will need a separate database for each environment, as you don't want to alter the production database with test content.  Creating a separate database for each environment is rather simple (you can create them through cPanel,) but the trick is getting Drupal to know which database is should use depending on which environment it is on.  This is where we need to leverage some trickery with the settings.php file.  (There may be better ways of doing this, but this method works rather well.)

Create a Settings.php for each environment

To start things off, create the following files:

settings.local.php
settings.dev.php
settings.staging.php
settings.production.php

In each of these files, you will add the database connection settings for that environment.  So, for instance, for the Dev environment, edit the settings.dev.php file, and add the following:

<?php

// Database for dev environment:
$databases['default']['default'] = array(
    'database' => 'account_drupdev1',
    'username' => 'account_drupal',
    'password' => 'password',
    'host' => 'localhost',
    'driver' => 'mysql',
    'port' => 3306,
    'prefix' => '',
);

Where you will replace the database name, user, and password accordingly (also, you may need to alter the port and add a prefix if you are using prefixed tables.)  Do the same for all 4 files, replacing the database name accordingly (the username and password will likely be the same, with the possible exception of your local database.)

The next step is to open the settings.php file (this is the main file, which Drupal will always use) and replace the code where the $databases array is defined with the following code:

$databases = array();

// Since the URI of the local environment is not standardized, we will
// just check if the local settings file exists (it should not exist on
// dev/staging/production servers.)  If it does, include that.
//
// Source: http://foggyperspective.com/article/environment-specific-settingsphp-overrides
if (file_exists(dirname(__FILE__) . '/settings.local.php')) {
    include dirname(__FILE__) . '/settings.local.php';
} else {
    // Determine the environment from the HTTP host.
    // Example:
    //    mysite.com = production
    //    www.mysite.com = production
    //    staging.mysite.com = staging
    //    dev.mysite.com = dev
    //
    //  Ideally, we would use local.mysite.com as the local environment,
    //  but that needs to be standardized for all developers.
    $host = $_SERVER['HTTP_HOST'];

    $subdomain = str_replace('domain.com', '', $host);
    $subdomain = str_replace('domain', '', $subdomain);
    $subdomain = str_replace('www', '', $subdomain);
    $subdomain = str_replace('prod', '', $subdomain);

    $subdomain = trim($subdomain, '.');
    $subfile = (strlen($subdomain) >= 1) ? $subdomain : 'production';
    $subfile = trim($subfile, '.');

    // Prefix configuration variables with 'pre_' to avoid conflicts:
    $conf['pre_environment'] = ucfirst($subfile);
    $conf['pre_settings_file'] = '/settings.' . $subfile . '.php';

    // Check if the file exists before including it:
    if (file_exists(dirname(__FILE__) . $conf['pre_settings_file'])) {
        include dirname(__FILE__) . $conf['pre_settings_file'];
    }
}

What this code is doing is looking at the URI, and determining which environment we are on.  This is assuming you used dev.domain.com and staging.domain.com as your subdomains (edit the code as necessary.)  Additionally, if you have a policy where all developers are to use a common URI for their local development environment, you could tweak the code above some more.  As it is, we are assuming that each developer might use a different URI (e.g. loc.domain.com, local.domain.com, www.domain.dev, etc.) and are simply looking for the existance of the local settings file to determine if we are on the local environment.  For this reason, it is important to add this file to the .gitignore file, but it might be useful to have a default.settings.local.php which contains the settings, and developers can rename to settings.local.php.  (If you push your settings.local.php file to the server, it will try to use that and most likely fail to connect to the database.)

Now, when you push these files to the server, Drupal should be able to determine which database to use based on the environment.