Can I change the PSR 4 Autoload Namespacing with a fallback?

时间:2016-04-04 18:30:02

标签: php composer-php autoload packagist

I have a public package on packagist/composer.

Originally it autoloaded with PSR-4 \GitHubUser\Package\Class for the file src/Class.php.

I would like to shorten this to \Package\Class for the same file. This is easily done by changing the composer.json. But is there a way I can do this with a fallback for people using the existing longer call? (autoload both?)

What I'd like:

"autoload": {
    "psr-4": {
        "PackageName\\": "src",
        "User\\OldPackageName\\": "src"
    }
}

But it doesn't register the 2nd call for the same folder.

1 个答案:

答案 0 :(得分:1)

You have to find a way that the one file that gets loaded defines the correct single class, or both classes. It might be doable, maybe duplicate the code, extend the class or something else.

On the other hand, that's what incompatible update versions are for. You can try and support the old name forever, or you can cut this legacy and only support the new name (why did you change it in the first place?).

Composer will not change the namespace line in the code, so the prefix in the autoloader cannot be changed at will - it has to be in the code. Also note that in order to be compatible to PSR4, referenced by PSR1, only one class per file is allowed.

What is the goal of this attempt? In order to make the old package name avaibable to the public, you can decide to support the old version a little bit longer, i.e. apply functional and security fixes. The new version would be marked with a higher major version number, and also supported. A migration guide would point out that the only requirement to update is to change the namespace, anything else would be the same. This results in a much cleaner upgrade path, because you can test both versions individually, and don't forget about corner cases.

Also you don't run into problems with type hinting, when a class from the old namespace has a typehint for the new class or vice versa (and this is likely impossible to change in code - at least it is way too uncommon that I want to think about a solution).

TLDR: Use two major versions for the two namespace-incompatible packages, and provide the user with the easy-to-do upgrade instructions.