mediatribe.net -- Drupal and Web Development

Notice: this post was last updated 3 years 43 weeks ago so it might be outdated. Please be cautious before implementing any of suggestions herein.

Drupal: Use module_load_include(), not require_once. Here is why

In Drupal 7, say you are in the module xyz and you want to include xyz.admin.inc., you should always use

<?php
module_load_include
('inc', 'xyz', 'xyz.admin');
?>

and not:

<?php
require_once dirname(__FILE__) . '/xyz.admin.inc';
?>

Here is a typical scenario where this breaks your site completely:

Say you start a project by downloading a bunch of modules to sites/all/modules.

Eventually, you have custom features, custom modules and contrib modules all in the same folder.

It is very common in this case to move modules to three sub-folders, contrib, custom, and features.

When you do this, Drupal's registry breaks down and you can no longer clear the cache, but the Registry Rebuild tool does a good job of rebuilding the registry.

However, rebuilding the registry only works if you don't have require_once directives lying around. These will break your site until you change them with module_load_include()s, rebuild your registry again, and clear your cache.

Some related Drupal issues I just filed:

https://drupal.org/node/2091251
https://drupal.org/node/2091253
https://drupal.org/node/2091255
https://drupal.org/node/2091257

How can the problem be solved

How can the problem be solved in a global context as in https://drupal.org/node/2091255?

The documentation for module_load_include() says:

Do not use this function in a global context since it requires Drupal to be fully bootstrapped...

Good point. In the case of

Good point. In the case of https://drupal.org/node/2091255, I've used the patch for some time with no issue, but still, it should not be done, I agree.

I was looking at the code of many established modules and few actually load external files in a global context. Perhaps it can be avoided entirely by using module_load_include() only in those functions that need it? That, combined with the dependency system and the autoload classes mechanism, might be all you need in your toolbox.

Right now I can't think of a use case where globally loading an external file can't be done with an alternate approach.

For the media module, in this comment, I documented a possible approach using autoload classes.