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:
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:
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:
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?
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.
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.
global $conf?
But where does global $conf come from?
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.
$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.
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.
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.
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.
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.