Same name and namespace in other branches

Load a module include file.

Examples:

// Load node.admin.inc from the node module.
module_load_include('inc', 'node', 'node.admin');

// Load content_types.inc from the node module.
module_load_include('inc', 'node', 'content_types');

Do not use this function to load an install file. Use module_load_install() instead.

Parameters

$type: The include file's type (file extension).

$module: The module to which the include file belongs.

$name: Optionally, specify the base file name (without the $type extension). If not set, $module is used.

16 calls to module_load_include()

File


  • includes/

    module.inc, line 280

  • API for loading and interacting with Drupal modules.


Code

function module_load_include($type, $module, $name = NULL) {
  if (empty($name)) {
    $name = $module;
  }
  $file = './' . drupal_get_path('module', $module) . "/{$name}.{$type}";
  if (is_file($file)) {
    require_once $file;
  }
  else {
    return FALSE;
  }
}

Comments

codycraven’s picture

When your included file is in a sub-directory, such as admin or includes, precede the $name parameter with the directory.

In the case of including my_module.include1.inc file within the includes directory in the my_module module:

  module_load_include('inc', 'my_module', 'includes/my_module.include1');
kenorb’s picture

If you have some WSOD, probably you have some function declared twice, activate: display_errors in php.ini, to see what's wrong or check the logs

Andrew Udvare’s picture

This function returns '' (empty string) if the include is successful and a definite FALSE if not. You could also test against '' (!= ''). This is because the function has no real return value if it is successful.

You should definitely do any checks for files long before, but if something is mission critical (or if you add an external lib to your module directory), this might be useful to have.

// If successful, this will still be true
if (!module_load_include('inc', 'some_module', 'an_inc_file')) {
}

// Same as above
if (module_load_include('inc', 'some_module', 'an_inc_file') == FALSE) {
}

// Hacky way to test, this if successful
if (module_load_include('inc', 'some_module', 'an_inc_file') == '') {
}

// Successful include
if (module_load_include('inc', 'some_module', 'an_inc_file') !== FALSE) {
}
dimsh’s picture

Hi Andy Udvare,

the function returns NULL when success, if there is no explicit return statement, it is always NULL.

NULL == ''; // true
NULL === ''; // false

you can check for success using:

is_null( module_load_include(...) ); 

regards,

greg.harvey’s picture

Worth noting, if you want to include data (e.g. a views object) in an include file, you cannot use this function - because the data will only be available within the scope of module_load_include() function, not within your own function that invoked it.

If you want to use module_load_include() for such a task, you need to wrap the object you need back in a function (which will be available beyond the scope of this function) with a return value of the data you need.

Otherwise you must require/include yourself and not use this function.

curiosity26’s picture

Yes, you do have to be careful were you place module_load_include() in your code. But you don't necessarily have to go out of your way to wrap it in functions. Proper placement can be more valuable than excessive function wrapping.

For example, I wanted an Events module I had written to tap into the Views 2 module. When I had written the module, I trusted that Drupal's table schema would use DateTime correctly, but it decided to save a String to the database, not the long integer Unix Epoch I had hoped for. This wasn't an issue until I had laid out my Views Data hook and realized the 'views_handler_field_date' only accepts the Unix timecode from the database and will NOT convert a string.

Luckily, there's a hook for that (Gotta love Drupal for its Hooks) and the smart cats who wrote Views were cool enough to let me tap that hook. So I copied the 'views_handler_field_date' handler and put a strtotime() function on the value and placed it in my module. I got a nice error telling me the 'views_handler_field' extension class couldn't be found.

This is where the module_load_include() came into play. But where to put it? I could stick it in the hook_views_handlers() function, but that would be a bit ambiguous and what if I need other handlers that won't be using this include; why load what isn't needed? Furthermore, would loading the include here allow my include to access it when it's actually being loaded by the Views module? After all, I'm just passing it along.

Solution: No functions, no crap like that. Just simplicity. I put module_load_include('inc', 'Views', 'handlers/view_handler_field'); on the line in my 'views_handler_field_date_string.inc' file (which is being passed through the hook to Views) just before the class definition. Just calling it straight forward and it worked like a charm. Drupal included the file right when I needed it and ignores it when I don't.

Furthermore, if Views isn't installed, the Hook is never called, so therefore, I never have to worry about including a 404. Even if I did, Drupal would keep plugging on and shoot me an error in the Watchdog.

johnnygamba’s picture

I was wondering if i must use this function instead of include_once always in Drupal.

siliconmeadow’s picture

Hi johnnygamba,

You can use include_once if you like, but this is a more drupal-ish method. module_load_include appears to be a wrapper around the require_once php function. I'd use it if I were you, but if you know what you're doing, and include_once can work for you.

HTH.

ngaur’s picture

I'm concerned by this:

  if (is_file($file)) {
    require_once $file;
  }

I run APC, so require_once doesn't actually result in any disk operations, but the is_file() check still proceeds, causing a bunch of unnecessary system calls, as in the listing below.

07:42:37.054662 getcwd("/var/local/www/xxx/htdocs"..., 4096) = 36 <0.000023>
07:42:37.054793 gettimeofday({1334043757, 54836}, NULL) = 0 <0.000019>
07:42:37.054911 lstat("/var", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0 <0.000022>
07:42:37.055072 lstat("/var/local", {st_mode=S_IFDIR|S_ISGID|0775, st_size=4096, ...}) = 0 <0.000022>
07:42:37.055235 lstat("/var/local/www", {st_mode=S_IFDIR|S_ISGID|0775, st_size=4096, ...}) = 0 <0.000024>
07:42:37.055400 lstat("/var/local/www/xxx", {st_mode=S_IFDIR|S_ISGID|0755, st_size=4096, ...}) = 0 <0.000023>
07:42:37.055568 lstat("/var/local/www/xxx/htdocs", {st_mode=S_IFDIR|S_ISGID|0755, st_size=4096, ...}) = 0 <0.000023>
07:42:37.055740 lstat("/var/local/www/xxx/htdocs/sites", {st_mode=S_IFDIR|S_ISGID|0775, st_size=4096, ...}) = 0 <0.000023>
07:42:37.055914 lstat("/var/local/www/xxx/htdocs/sites/all", {st_mode=S_IFDIR|S_ISGID|0775, st_size=4096, ...}) = 0 <0.000025>
07:42:37.056090 lstat("/var/local/www/xxx/htdocs/sites/all/modules", {st_mode=S_IFDIR|S_ISGID|0775, st_size=4096, ...}) = 0 <0.000026>
07:42:37.056269 lstat("/var/local/www/xxx/htdocs/sites/all/modules/memcache", {st_mode=S_IFDIR|S_ISGID|0775, st_size=4096, ...}) = 0 <0.000030>
07:42:37.056456 lstat("/var/local/www/xxx/htdocs/sites/all/modules/memcache/memcache.inc", {st_mode=S_IFREG|0775, st_size=18058, ...}) = 0 <0.000028>
07:42:37.056649 open("/var/local/www/xxx/htdocs/sites/all/modules/memcache/memcache.inc", O_RDONLY) = 6 <0.000036>
07:42:37.056806 fstat(6, {st_mode=S_IFREG|0775, st_size=18058, ...}) = 0 <0.000020>
07:42:37.056967 stat("./sites/all/modules/memcache/memcache.inc", {st_mode=S_IFREG|0775, st_size=18058, ...}) = 0 <0.000023>
07:42:37.057171 close(6)                = 0 <0.000023>

That adds up when it's done 500 plus times for every http request.

Why not just call include_once and test the return code?