-- 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, you should always use

('inc', 'xyz', 'xyz.admin');

and not:

require_once dirname(__FILE__) . '/';

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:

How can the problem be solved

How can the problem be solved in a global context as in

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, 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.