4

In my custom module, I've included a file using files[]=foo.php in the .info file. foo.php declares classes in a namespace.

Drupal does not seem to be autoloading this class: in my main module file $foo = new Foo\Bar(); causes a Class Not Found error.

Is this because Drupal 7's registry can't cope with namespaces?

4

Yes, Drupal 7 knows nothing of namespaces unfortunately (namespaces were only introduced in PHP 5.3 and D7 is compatible with earlier versions than that).

However, life gets infinitely better with the XAutoload module, which is PSR-0 compliant an thus knows all about namespaces.

xautoload is a comprehensive and yet highly efficient PHP class loading suite. Most importantly, it provides Drupal-8-style PSR-0 autoloading for Drupal 7.

The latest release is even moving towards PSR-4 which is great news.

If you install that module you can remove all of the files[] references from your info files, as long as you follow the \Drupal\my_module namespacing pattern. Even if you don't, XAutoload has hooks to let you define your own patterns.

|improve this answer|||||
  • Sounds great, I'll check it out. Like that it's forward looking to D8, although this library code is not going to be in the Drupal/ NS, so maybe I'll always need xautoload even in d8... – artfulrobot Sep 2 '13 at 10:07
  • I haven't checked, but chances are you'll be able to hook into D8's autoloader to provide custom root namespaces. In fact since there's so much 3rd party vendor code in there, that's pretty much a certainty – Clive Sep 2 '13 at 10:15
  • 1
    UPDATE: The xautoload-7.x-4.x branch has PSR-4 support, and it can generate classmaps by scanning a directory (and unlike core, this does support namespaces). function MYMODULE_xautoload($api) { $api->addClassmapSources(array('lib/**/*.php'));} this will scan the folder and cache the result. @Clive should I update your answer? – donquixote Dec 29 '13 at 21:21
  • @donquixote awesome, I shall grab a copy and check it out. And yeah, please feel free to update the answer that would be great – Clive Dec 29 '13 at 22:43
  • @Clive: I'm sorry, my "update" is getting way too long to edit your answer, so I will make it a separate one. I think your 67k reputation can handle it :) – donquixote Dec 29 '13 at 23:23
4

As Clive said above, the Drupal 7 core registry cannot handle namespaces, but [xautoload][https://drupal.org/project/xautoload] is your solution!

The xautoload-7.x-5.x branch has PSR-0 and PSR-4 support, and it can generate classmaps by scanning a directory (and unlike core, this does support namespaces).

Now you have a number of options:

  1. Use PSR-4 like in Drupal 8, with your classes in the /src/ directory. See https://www.drupal.org/docs/develop/standards/psr-4-namespaces-and-autoloading-in-drupal-8
  2. Put your classes in arbitrary files, and let xautoload scan these files. The result will be cached in the regular Drupal caches, so you need to flush the caches whenever you add a new class file. This is very similar to the Drupal 7 core class registry, but it does support namespaces.

    /**
     * Implements hook_xautoload()
     */
    function MYMODULE_xautoload($api) {
      // Add directories to discover php files with classes.
      // You can be creative with the wildcards.
      // '**' means to scan subdirectories of any depth.
      $api->addClassmapSources(array(
        'includes/**/*.inc'
      ));
    }
    
  3. Put your classes in arbitrary files, avoid namespaces, and use the D7 core registry + xautoload wildcards. Put this in your MYMODULE.info file:

    files[] = includes/**/*.inc
    
  4. There are some options that are supported for legacy reasons, but these should not be mentioned here.

An alternative is registry_autoload, which uses the regular core registry, but supports namespaces and detects classes automatically.

Advantage of registry_autoload: More light-weight (but does not mean it is faster, the jury is still out on this).

Advantage of xautoload: During development, classes are immediately available without running the registry build.

|improve this answer|||||
  • I should mention that this answer is a bit outdated. Xautoload now supports PSR-4 as in Drupal 8, out of the box. – donquixote Jan 4 '17 at 2:13

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.