0

I was trying to understand how Drupal 8 initializes the class loader to look for files containing classes in core/lib and modules/*/src.

I found out that the class loader is set to an instance of ApcClassLoader in DrupalKernel::initializeSettings().

  // If the class loader is still the same, possibly upgrade to the APC class
  // loader.
  // ApcClassLoader does not support APCu without backwards compatibility
  // enabled.
  if ($class_loader_class == get_class($this->classLoader)
   && Settings::get('class_loader_auto_detect', TRUE)
     && extension_loaded('apc')) {
    $prefix = Settings::getApcuPrefix('class_loader', $this->root);
    $apc_loader = new \Symfony\Component\ClassLoader\ApcClassLoader($prefix, $this->classLoader);
    $this->classLoader->unregister();
    $apc_loader->register();
    $this->classLoader = $apc_loader;
  }

Following the methods that are called after that, I cannot find the exact method setting the class loader to correctly find the files containing Drupal classes. I expect it to be done from Drupal code, since the directory layout is very specific for Drupal.

Which method set the class loader to look in the right directories Drupal uses?

  • I am trying to port the code to Drupal 7, to use it in a module that would allow modules to use composer.json to load their dependencies and have a class loader that is based on the one Composer uses. I am using the composer.json file Drupal 8 comes with, as base. – kiamlaluno Apr 7 '16 at 17:53
  • The answer is simple: Magic 🙌 – Eyal Apr 8 '16 at 14:26
  • On a serious note: look inside the /core/composer.json file. It contains a class loader class, that is provided by drupal core. – Eyal Apr 8 '16 at 14:30
  • @Eyal The only reference to a class loader I see there is for symfony/class-loader, which is one of the Symfony components. – kiamlaluno Apr 8 '16 at 15:04
1

For modules with composer dependencies in 7.x, try https://www.drupal.org/project/composer_manager. If you want to support modules with PSR-4 autoloading, see https://www.drupal.org/project/registry_autoload (integrates with the standard 7.x class loading registry) or https://www.drupal.org/project/xautoload.

That said, the code you pasted is just the APCu wrapper for the class loader. The actually relevant line is this, in \Drupal\Core\DrupalKernel::discoverServiceProviders():

$this->classLoaderAddMultiplePsr4($this->getModuleNamespacesPsr4($module_filenames));

What it does is register a PSR-4 namespace for each module with composer. Below that, everything follows the standard rules.

But composer dependencies is something else, that's handled automatically by composer's autoload.php and all the files that that then loads. Which is basically what composer_manager does, load the generated autoload.php file.

| improve this answer | |
  • The Composer manager module does indeed creates the composer.json file from all the composer.json files used by modules; the problem is that does it in the server it is installed, which is not what I need. – kiamlaluno Apr 7 '16 at 19:57
  • I'm not sure what you mean with "does it in the server it is installed". While it's not the officially recommended approach, you can run composer manager & composer update/install anywhere and commit the result, then it's available everywhere, for everyone. – Berdir Apr 8 '16 at 6:18
  • Yes, but the composer_manager module doesn't run anywhere. If I copy the Drupal files in /home/kiamlaluno/drupal-7, add a composer.json file in /home/kiamlaluno/drupal-7. and copy a module's files (including its composer.json file) in /home/kiamlaluno/drupal-7/sites/all/modules/my_custom, the composer_manager module doesn't do anything. – kiamlaluno Apr 8 '16 at 7:42

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.