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 thevendor
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 :