Drupal 8 embraces modern PHP with all the trimmings, shedding the baggage of supporting earlier PHP versions and embracing the new object-oriented features.

One such feature is namespaced objects and the PSR-0 standard for autoloader compatability.

But if you know your project will run on a recent version of PHP, there's no reason you can't write your custom modules using PSR-0 now, in Drupal 7

What is a namespace

So first some background. What is a namespace? I was speaking with someone on irc recently and I quoted the fully-qualified name of a Drupal 8 object. Let's use \Drupal\image\Entity\ImageStyle as an example: their response was 'I freak out whenever I see those forward slashes'. But there is no need to freak out. Namespaces allow us to use the same class name more than once. Consider the Request class; in Drupal 8 there are three objects with a short-name Request as follows:

  • Symfony\Component\HttpFoundation\Request
  • Zend\Stdlib\Request
  • Guzzle\Http\Message\Request

In most cases you wouldn't need all three in the one file, you'd nominate which one you want to use with a use statement, eg. use Guzzle\Http\Message\Request and from then on that object can be simply referred to as Request

Therefore, if we didn't have namespaces, these objects would have to be given more verbose names such as Symfony_Component_HttpFoundation_Request and Zend_StdLib_Request to avoid clashing. You'd also have to use these full names every time you interacted with that class, which clearly would suck.

What is PSR-0

PSR-0 is an autoloader standard: if you define your class namespaces using the PSR-0 standard, they're compatible with other PHP libraries and code-bases that also follow PSR-0. PSR-0 ensures everyone gets along.

Autoloading in Drupal 7

Now in Drupal 7, we have our own autoloader. PSR-0 didn't exist as an accepted standard when Drupal 7 was developed, so instead we have our own autoloader that is based on modules declaring files to parse for objects in their info file using files[] entries.

X autoload - PSR-0 in Drupal 7

So how do you use PSR-0 namespaces in Drupal 7? Well the answer is simple, you use the excellent X autoload module by @donquixote. Just be sure to add it to your module's dependencies.

Once you enable the module, you can remove all of the files[] entries in your module's info file and rely on placing your classes in the correct PSR-0 folder structure instead.

So if your module is named robot and your fully-qualified class-name is Drupal\robot\Action\Destroy, you need to place the file containing the class in sites/all/modules/robot/lib/Drupal/robot/Action/Destroy.php, just like Drupal 8.

For an example of how much the module can clean up your info files, take a look at this example from views module. Granted it's an example using some of the other non PSR-0 features of X autoload but the difference is even more telling when you use PSR-0, as you have no files[] entries in your info file.

Disclaimer

It is highly likely that Drupal 8 will ship using the PSR-4 standard, instead of or in addition to PSR-0. The good news is xautoload also supports PSR-4, so when that change occurs in Drupal 8, it's a relatively simple change to make to your folder structure to move to PSR-4.

Comments

Nice writeup! Alternate autoloading technique's picture
Nice writeup! A...

Thanks for the writeup. I also wanted to point out that you can use the Composer Manager module to enable PSR-0/4 autoloading in your module as well. To do this, the maintainer must add a composer.json file to their module's root directory and then follow Composer's documentation to register the namespace. The downside is that you have to run the Composer tool to register the autoloader unlike Xautoload which is native to Drupal, but the benefit is that you can also use the composer.json file to pull in third-party libraries that your module can benefit from.

Hugh's picture
Hugh

It is now confirmed, PHP class autoloading changed to PSR-4 instead of PSR-0
https://drupal.org/node/2246699

donquixote's picture
donquixote

Just saying, to get the full PSR-4 support as in D8, you need to let your module depend on xautoload >= 7.x-5.x, so

dependencies[] = xautoload (>= 7.x-5.x)

Post a comment

Type the characters you see in this picture. (verify using audio)
Type the characters you see in the picture above; if you can't read them, submit the form and a new image will be generated. Not case sensitive.