Blog RSS Feed Subscribe

Jordi Boggiano

Jordi Boggiano Passionate web developer, specialized in web performance and php. Partner at Nelmio, information junkie and speaker.

Categories

PSR-4 autoloading support in Composer

As of today and thanks to a pull request by Andreas Hennings who did the bulk of the work, we have PSR-4 autoloading support in Composer. It is a feature that can have a serious impact on users of your packages so I wanted to detail what it means for everyone.

First of all if you are not familiar with PSR-4 but know about PSR-0 the main difference and benefit is that it allows for flatter directory structures in your git repositories. While you typically had src/Vendor/Lib/Class.php in libraries it is now possible to use a simpler src/Class.php while retaining the namespacing at the code level. The other small difference is there no more support for PEAR-style namespacing of classes using underscores (e.g. Vendor_Lib_Class) so those packages should keep using PSR-0 and not migrate.

So we can use it in Composer now, and that's cool. I am sure some of you already stopped reading and are pushing changes to your repos to be using the new shiny, but please don't. Not just yet.

The issue is that Composer support for PSR-4 is needed for your packages to autoload properly. If you push this out now, people are going to freak out as soon as they update your package and classes can not be autoloaded anymore. In addition we will for sure have a ton of bogus support requests, and perhaps you too. Therefore I would like to urge everyone to wait at least until February before using this in any semi-popular package. I will tag a new release of Composer soon so that homebrew users for example also get the PSR-4 support in a timely manner.

For the gory details you can head to the Composer documentation, but it's fairly straightforward to upgrade. To only upgrade at the Composer level only you can just update mappings like this:

// before
{
    "autoload": {
        "psr-0": {
            "Foo\\Bar\\": "src/"
        }
    }
}

// after
{
    "autoload": {
        "psr-4": {
            "Foo\\Bar\\": "src/Foo/Bar/"
        }
    }
}

While if you want to benefit from the shorter paths it is even more simple, you turn the psr-0 into a psr-4 and move all the files from src/Foo/Bar/* into src/*

Finally, a quick note for users of the target-dir property (mostly that is Symfony2 bundle authors as far as I know). The property is now deprecated and using it together with PSR-4 is forbidden since was essentially a hack to support PSR-0 autoloading in non-standard repositories. If you were using that you can easily get rid of it by updating the composer.json as such:

// before
{
    "autoload": {
        "psr-0": {
            "Foo\\BarBundle\\": ""
        }
    },
    "target-dir": "Foo/BarBundle"
}

// after
{
    "autoload": {
        "psr-4": {
            "Foo\\BarBundle\\": ""
        }
    }
}

Thanks for your attention, and again please refrain from jumping on this too quickly to save everyone some trouble. And while I am at it: Happy new year!

January 03, 2014 // PHP

Post a comment

Subscribe to this RSS Feed Comments

2014-01-03 17:01:27

Greg

In few month,s could we replace all psr-0 by psr-4 in our composer.json, even if we don't use psr-4 feature ? I just want something normalized ;)

2014-01-03 17:02:33

Wouter J

"The other small difference is there no more support for PEAR-style namespacing of classes using underscores (e.g. Vendor_Lib_Class). "

Does this mean twig cannot be autoloaded using composer anymore?

2014-01-03 17:16:50

Barry vd H

@Wouter J, PSR-0 will not be changed, PSR-4 is just an alternative for a simpler directory structure. Twig can just keep using PSR-0 :)

2014-01-03 17:29:35

Andrew S

Wouter J from what I can tell you would still be able to load that using psr-0, since the autoloader should be able to handle both.

2014-01-03 20:25:16

Ersan

I was anticipating this merge after playing with Andreas' code. Just tried it now and it works like a charm! Very happy...

2014-11-07 06:55:18

Mathieu D.

I think that the target-dir property was also useful for integrating sub-packages in a package (with "replace"), like symfony does for its components (debug, console, ...).
Without the target-dir and the psr-4's flatter directory structure, how is it done in psr-4?
I posted this question with more details in Google groups: https://groups.google.com/forum/m/#!topic/composer-users/JOAYf8Ic0j0

2014-12-06 21:03:24

Nico

goo info man, thanks!

2015-08-24 14:14:26

Alejandro

Thank you very much for this post!