Quick news

  • 2014-03-27: MongoDB Watchdog module ported to Drupal 8 at the Szeged Dev Days.
  • 2014-01-26: My post on the Symfony web profiler in Silex selected in Week of Symfony. w00t !
  • 2013-10-18: My first commit went into MongoDB today. And, guess what ? It's in JavaScript
  • 2013-09-20 to 29: Working on Drupal 8 EntityAPI at the extended code sprints during and around DrupalCon Prague
  • 2012-08-19: Working on Drupal 8 EntityAPI at Drupalcon Munich
  • 2012-06-15: Working on Drupal 8 EntityAPI at DrupalDevDays Barcelona
  • 2012-03-23: Working on the future Drupal Document Oriented Storage at DrupalCon Denver. D8 or later ? Bets are on Later

PSR-4, really ?

Yesterday, Seldaek committed PSR-4 support to Composer, as his New Year's Day gift to the PHP community.

So, since I always supported PSR-4 in FIG discussions, and after the tl;dr discussion about it regarding autoloading in Drupal 8, I jumped on the occasion and converted the code base for PlusVite to PSR-4 to get an idea of how PSR-4 "felt" in practice.

A the documentation explains, to convert from PSR-0 to PSR-4 to shorten paths, the change is extremely simple: just edit your composer.json and change it like this:

  PSR-0 PSR-4 with PSR-0 layout Pure PSR-4
\Foo\Bar\Bazclass is in src/Foo/Bar/Baz.php src/Foo/Bar/Baz.php src/Baz.php
composer.json contains "psr-0": { "Foo\\Bar\\": "src/" } "psr-4": { "Foo\\Bar\\": "src/Foo/Bar/" } "psr-4": { "Foo\\Bar\\": "src/" }

Of course, removing two levels of directories provided the expected small degree of instant gratification, making everything seem simpler. But then, doubt appears: maybe this is just because I've been using PSR-0 for too long (3 years, already ?), but now, seeing these namespaced classes/interfaces/traits in short paths like src/Baz.php for a simple project like this seems to be hiding information, degrading DX instead of improving it. Eewww !

Now, in Drupal 8, the situation is different: classes core modules are located under

core/modules/(module)/lib/Drupal/(module)/(subnamespace hierarchy)/someclass.php

while PSR-4 will change this to

core/modules/(module)/lib/(subnamespace hierarchy)/someclass.php

so the "hiding" effect will not be the same, since the name of the module (hence the namespace) will be in plain sight. But still, this is an unexpected feeling and I hope we will not regret it later on.

"Hiding information"

You hit a nerve here! There has been quite some resistance against PSR-4 in the Drupal thread, but I did not have much sympathy with the arguments. But the "hiding information" seems like a valid and relevant point!

I think it all boils down to how much you mentally identify the module directory with the module namespace. If the package namespace is rather arbitrary, then the two empty parent directories will immediately tell you about the package namespace (or the module namespace, in our case).

Now I am confused :)

Does not apply for modules

The "hiding information" or "eating part of the namespace root" effect only affects full libs.
\Drupal\module\Foo\Bar\Baz being in [module]/lib/Foo/Bar/Baz.php hides no information and only keeps the "intuitive, not needlessly verbose" effect.

Which is why "PSR-0 for external libs" and "PSR-4 for drupal modules" is a good fit.

Just to clarify, I still want

Just to clarify, I still want PSR-4 for Drupal modules.
But I appreciate you actually tried this before posting your critical thoughts!

Good Point

I'm trying to move some of my classes on PSR-4 but I'm feeling like it introduce a lot of confusion.

Now it is more than one month I moved some side libraries with PSR-4 standard but I'm thinking to switch back to PSR-0.

Despite the duplicated vendor-name/module in PSR-0 I feel more comfortable with this standard.

When I build a library I would like to have a structure:

src/CompanyName/Module/[Sub/]Class.php
tests/CompanyName/Module/[Sub/]Class.php
...
xxx/CompanyName/Module/[Sub/]Class.php

than:

/CompanyName/Module/src/[Sub/]Class.php
/CompanyName/Module/tests/[Sub/]Class.php
...
/CompanyName/Module/xxx/[Sub/]Class.php

when I use that library somewhere, it will be installed in vendor/companyname/module/src/CompanyName/Module/[Sub/]Class.php (that is not cool obviously), but my point is, once Composer installs that for you in the vendor dir, you don't have to care at what inside vendor, don't you?

I still think PSR-0 is the best way to setup directory structure, I don't understand why Composer installs it in that way??? Maybe I lost something but I would be more than happy to understand why composer can't manage PSR-0 to install libraries without "companyname/module/src" and starts directly from the NS.

vendor/CompanyName/Module/[Sub/]Class.php

am I losing something?

Obviously It's my personal tough.
Rosario

Composer is not the sole PSR-0 implementation

I do not really see your point: while working on the module itself, you do not even need to include CompanyName/Module, since this is your "main project" at this point, and you could just as well use a layout like:

src/[Sub/]Class.php
test/[Sub/]Class.php

This is only needed to group projects by vendor to avoid name collisions. If the paths started by src|test instead of the company name, you could get a vendor/src/(companies) directory, meaning vendor/src would mix vendors and vendor/test would mix them too. The current Composer layout seems better for packaging.

Also, note that :

  • this is in no way related to PSR-4
  • Composer is but one implementation (albeit the most popular) of PSR-0, PSR-4 and other autoloading strategies : you could just as well use your own autoloader using a layout different from Composer's. It could even still use Packagist as its main repository source.