Suggestions for settings.php - Local dev, Development server, Live server
-
16-10-2019 - |
문제
Basically, one of the greatest questions of all time: What are some ways you're using settings.php in your development/staging workflow?
Right now, I have my settings.php file set up like the following, and I base my development on the server's $HOST directive—meaning I can work on dev.example.com for the development (shared) server, local.example.com for my local computer (and other dev's local code checkouts), and www.example.com (or just example.com) for the live site.
(This code is in the 'Database settings' section of settings.php):
$host = $_SERVER['HTTP_HOST'];
$base_url = 'http://'.$host;
$cookie_domain = $host;
switch($host) {
case 'example.com': # Production server
$db_url = 'mysqli://prod_sql_user:password@127.0.0.1/prod_db';
$update_free_access = FALSE;
$conf = array (
// Set production config options here...
'example_setting' => 0,
);
break;
case 'dev.example.com': # Development server
$db_url = 'mysqli://dev_sql_user:password@127.0.0.1/dev_db';
$update_free_access = FALSE;
$conf = array (
// Set production config options here...
'example_setting' => 0,
);
break;
case 'local.example.com': # Local server
$db_url = 'mysqli://local_sql_user:password@127.0.0.1/local_db';
$update_free_access = FALSE;
$conf = array (
// Set production config options here...
'example_setting' => 0,
// Turn off most core caching.
'cache_inc' => 'includes/cache.inc',
'cache' => CACHE_DISABLED,
);
break;
}
?>
This works pretty well for most purposes, but it means we have a lot of extraneous code sitting around in our shared settings.php file... is there a better way?
해결책
What I do is separating that file into a settings.php and a local.settings.php.
At the end of settings.php is the following code:
if (file_exists(dirname(__FILE__) . '/local.settings.php')) {
include dirname(__FILE__) . '/local.settings.php';
}
The local file is then excluded from whatever VCS you are using. The advantage is that you can put settings which are common over all instances in settings.php and have that versioned/distributed automatically and keep the local stuff in local.settings.php.
다른 팁
This seems like you're reinventing Drupal's built in multisite functionality.
Personally, I keep all standard themes and modules for the site in sites/all
, and then have sites/dev.example.com
and sites/example.com
.
As an added bonus you can then have different files
folders for each site, and you can add any development modules to sites/dev.example.com/modules
as well.
I prefer to ignore the file locally (using a .gitignore
file in git) and then keep separate versions if the file on each host.
I tend to always set up DNS or host file entries and use
dev.example.com
staging.example.com
and
example.com
Then I have completely separate settings file directories with differing files directories. For instance ./sites/dev.example.com/files
Why not have a few folders based on the development host name?
Example
- sites/dev1.domain.com
- sites/dev2.domain.com
- sites/dev3.domain.com
- sites/www.domain.com
Each with their own settings file and db_url.
If the only things changing are the database credentials, then you can set environment variables in your local (and staging/production) virtual host config or in a .htaccess a folder above your web root. Here's a simple example:
/var/www/example.com/drupal-resides-here
I can then create a .htaccess file here:
/var/www/example.com/.htaccess
which has the following code:
SetEnv DB1_USER my_local_user
SetEnv DB1_PASS my_local_pass
SetEnv DB1_HOST my_local_host
SetEnv DB1_NAME my_local_dbname
Then in /var/www/example.com/drupal-resides-here/sites/default/settings.php
(or whatever) you can grab the db credentials like:
$db_url = "mysql://{$_SERVER['DB1_USER']}:{$_SERVER['DB1_PASS']}@{$_SERVER['DB1_HOST']}:{$_SERVER['DB1_PORT']}/{$_SERVER['DB1_NAME']}";
This lets multiple developers run things locally and you can push to staging / production while still tracking settings.php (there are more things in there than just the database credentials...). You also wouldn't have to keep track of multiple settings.php files.
Simplest and most efficient solution that is just one line is the following. Just include it in the last line of your settings.php file:
@include('settings.local.php');
The @ symbol in the front just means don't display any error even if it doesnt find that file. Typical setup's like this involve a conditional to check if the file is there. This accomplishes it in one line without it.
http://php.net/manual/en/language.operators.errorcontrol.php
Also known as the STFU PHP operator.