By zzolo
2010, February 17 - 10:22am

Tip for Managing Variables in a Drupal Module: Naming conventions, please.

Update via Garrett Albright (see comments)

Just a quick tip for managing variables in a Drupal module. Please prefix your variables with your module name. For example:

  1. variable_set('examplemodule_variable_name', 1234);

This ensures that another module won't override your variable, or your module won't do the same thing. Pretty simple. But what is also nice, is that you can clean up after your module a lot easier in the uninstall hook:

  1. /**
  2.  * Implementation of hook_uninstall().
  3.  */
  4. function examplemodule_uninstall() {
  5.   // Get global variable array
  6.   global $conf;
  7.   foreach (array_keys($conf) as $key) {
  8.     // Find variables that have the module prefix
  9.     if (strpos($key, 'examplemodule_') === 0) {
  10.       variable_del($key);
  11.     }
  12.   }
  13. }

Please note that the above convention could cause problems if your module name is something like content_permissions and then the content module (CCK) defines a variable with a conflicting name. All the more reason to make your module names more unique and without underscores.

Old code that needlessly queries the database:

  1. /**
  2.  * Implementation of hook_uninstall().
  3.  */
  4. function examplemodule_uninstall() {
  5.   // Get module variables
  6.   $results = db_query("SELECT v.name FROM {variable} AS v WHERE v.name LIKE '%s%%'", 'examplemodule_');
  7.   // Remove variables
  8.   while ($row = db_fetch_array($results)) {
  9.     variable_del($row['name']);
  10.   }
  11. }

10 comments

 
Chris Cohen wrote 28 weeks 6 days ago

Agree

Couldn't agree more with regard to variable names. It's not something that springs immediately to mind, to prefix variable names with your module name, but it is essential for avoiding unexpected conflicts later on, which WILL be extremely hard to debug.

The 'to use underscores or not' argument for naming contrib modules continues to rage, but there's no doubt it's safer not to use them, so best to err on the side of caution, right?

 
Garrett Albright wrote 28 weeks 6 days ago

No need to use the DB layer

No need to use the DB layer to do this… I do something like this in the hook_uninstall() of my modules:


global $conf;
foreach (array_keys($conf) as $key) {
if (strpos($key, 'examplemodule_') === 0) {
variable_del($key);
}
}

The filters seem to be eating my spacing, but hopefully you get the idea.

 
zzolo wrote 28 weeks 6 days ago

Much better

Agreed; this is a better way to do this, as Durpal loads the variable table into $conf already. I will update the article.

 
greggles wrote 28 weeks 6 days ago

global $conf?

But where does global $conf come from?

 
extra cautious wrote 28 weeks 6 days ago

oh... dangerous

Oh... dangerous. I always like to explicitly define this. It takes more effort on the developers part but it would really suck if you deleted all the variables for some examplemodule_awesomer module. I also avoid dynamically named variables for the same reason.

 
extra cautious wrote 28 weeks 6 days ago

$conf

@greggles $conf is where the variable_* functions store the variables they load in from the db.
http://api.drupal.org/api/function/variable_get/6

PS - I meant the hook_uninstall implementation. The prefixing is definitely a good idea. There even used to be a patch to have explicit name-spacing for variables. I'd still like to see that happen someday.

 
Garrett Albright wrote 28 weeks 6 days ago

extra cautious, ideally, the

extra cautious, ideally, the examplemodule_awesomer module would be dependent on the examplemodule module, so examplemodule_awesomer would have to be uninstalled (have its own hook_uninstall()) called before examplemodule could be uninstalled. So this method shouldn't delete anything that shouldn't already be deleted - again, ideally. If your module has a common name and there could easily be a collision, you'd want to be cautious; for example, if your module was called "uc" and you took this approach, you'd delete every single variable the Ubercart suite uses! But in most cases, such a collision needn't be worried about. And though forcing namespacing for variables is a good idea, I don't know if it would necessarily solve problems in this regard unless the namespacing used a name which could be more unique than the module's name - maybe a CRC32 hash of the name instead?

greggles, I'm not sure if your message was implying that there's some security problem with my approach - if so, please elaborate, because I do have a couple of modules active on D.o which do this. But if you were in earnest, the $conf array is initially defined in conf_init(), which is called during the DRUPAL_BOOTSTRAP_CONFIGURATION stage of bootstrapping.

 
Dave Reid wrote 28 weeks 6 days ago

When in doubt, follow the example set by Core

Always, always use explicit variable_del(), which is what all core modules do. There's too many things that could go wrong with running blanket SQL statements like that.

In a couple of my modules I like to have a hook_variables() implementation (note: this hook doesn't do anything technically). I can than use that in my module's uninstall.

In mymodule.module:

function mymodule_variables() {
return array(
'mymodule_option1' => 'option1_default',
'mymodule_option2' => 'option2_default',
);
}

In mymodule.install:

function mymodule_uninstall() {
drupal_load('module', 'mymodule');
$variables = array_keys(mymodule_variables());
foreach ($variables as $variable) {
variable_del($variable);
}
}

This way I can see all my default values in one place, and whenever I add a variable, I add it to the mymodule_variables() function.

 
zzolo wrote 28 weeks 6 days ago

Just to clarify. I was never

Just to clarify. I was never using an SQL query to remove variables, just to get names. Good points, though.

 
Aaron Winborn wrote 28 weeks 6 days ago

Maybe double__underscore?

Perhaps you could use my_module__variable_name, noting the double underscore after the module name. I don't like the idea of just wiping out variables en mass. Note that we've just implemented a version of the registry (that didn't get into core) for the Media module: http://drupalcode.org/viewvc/drupal/contributions/modules/media/media.va.... I think I'll go in there and add the double underscore actually, to make it less likely to collide.

Recent Books

Haiku and a Portrait

The Uncertainty Principle

Floating on the air
everywhere and somewhere,
nowhere, only here.

The Tweet of Zzolo

  • Fact: I am so not good at not taking on too many things at once. Careful if I tell you I can do something. :)
    17 hours 55 min ago
  • @seutje That sounds positive. I am still of the opinion that iTunes is a bad piece of software I am forced to used given decent hardware.
    18 hours 12 min ago
  • Awesome. Thanks Apple for making the already terrible iTunes interface even worse.
    18 hours 45 min ago
  • @randyfay Awesome posts yesterday and today! Thanks!
    23 hours 32 min ago
  • Want IE 6,7,8 on your Mac (for Web Development only)? Check out WineBottler: http://winebottler.kronenberg.org/
    1 day 32 min ago

Twitter Icon Flickr Icon LinkedIn Icon Facebook Icon Drupal Association, Individual Member icon