Managing Variables in Drupal 7
A couple of times recently the issue of managing variables in Drupal 7 has come up in conversation with other developers. This post outlines the various ways of managing variables in Drupal sites. The three things this guide ensures:
- Sensitive data is kept secure
- Variables are correct in each environment
- You are able to track your variables (and when they changed)
The Variables Table
The most common place you’ll find configuration variables is in Drupal’s
variable table (aka {variable}
). The values in this table are often
managed via admin forms that use
system_settings_form()
.
Users enter the values click “Save configuration” and the data is stored
in the database.
If you prefer to manage your configuration via the command line and know
the variable you wish to set you can use drush vset
. This
does exactly the same thing as admin form, without needing to click on a
mouse.
$conf Array
While the variables table is great at storing our variables, there are
times when you want to enforce a setting. This might be because you want
to prevent users from changing it (accidentally or otherwise) or because
you need it to be different in each environment. The $conf
array in
settings.php always overrides any values in the variable table.
Acquia, Pantheon and platform.sh all provide environment variables so you can use different values in your $conf array depending on the environment.
Exporting Variables
In Drupal 7, the common way to export your variables is by using Strongarm with Features. I’m not going to cover how to do this as there is loads of documentation already available on this topic.
If your variable changes on a per environment basis or if it calculated on the fly, then you won’t want to use strongarm+features as the exported values are static. You will need to put them in settings.php.
Note to self: I should debug and reroll my patch for adding support in alter hooks strongarm.
My settings.php is Out of Control!
This is a common problem, especially on more complex sites. To avoid
this I recommend creating sites/default/settings/settings.[env].php
files. Your settings.php
file should check for the environment in an
environment variable and then include the appropriate
settings.[env].php
file.
What About Sensitive Data?
You can encrypt variables on a case by case basis using the encrypt
module and some custom code similar
to what I recently implemented in the Acquia SDK
module (see on
store
and on
read
examples). Warning: This doesn’t encrypt the data if you’re using drush vset
.
If you are storing sensitive data in your variables table I would
recommend you implement hook_sql_sync_sanitize()
which will delete
the sensitive data from your db when drush sql-sanitize
or drush sql-sync --sanitize
are run.
How to Decide?
This little code snippet should help you decide.
<?php
// Don't try using this code in your Drupal site.
if (!using_version_control()) {
// Seriously there is no point in doing this without version control.
abandon_all_hope();
drupal_exit();
}
if (is_data_sensitive($var)) {
$var = encrypt_var($var);
if (!we_use_drush_based_workflows()) {
learn_and_implement_drush_based_workflows();
// I'm serious!
}
}
implement_hook_sql_sync_sanitize($var);
}
if (is_unique_per_environment($var)) {
store_conf_array($var);
}
else {
store_in_db($var);
if (!we_use_features_based_workflow()) {
learn_and_implement_features_based_worflows();
// I'm serious!
}
export_using_strongarm($var);
}