5

Introduction

I'm using Laravel 4 and have two composer packages with the same namespace, autoloaded with PSR-0. The simplified schematics of the composer.json files are as follows.

Laravel app composer.json

{
    "require": {
        "laravel/framework": "4.2.*",
        "xxxxx/packageA": "1.2.0"
    }
}

xxxxx/packageA composer.json

{
    "require": {
        "xxxxx/packageB": "~2.1.0"
    },
    "autoload": {
        "psr-0": {
            "NS": "src/"
        }
    }
}

xxxxx/packageB composer.json

{
    "autoload": {
        "psr-0": {
            "NS": "src/"
        }
    }
}

The Question

So, xxxxx/packageA and xxxxx/packageB both have a NS namespace in the src directory. Does this work? I'm getting an error saying that class NS\\X was not found. Is this a Composer restriction with packages having the same namespace or this is fine and I have a error in my code?

pasadinhas
  • 353
  • 2
  • 6
  • 22

1 Answers1

4

You should try to avoid defining the same prefix twice for performance reasons.

Technically Composer does not have a problem with two packages defining a directory for the same prefix. But this forces Composer to check one of the directories first if it contains that class. On failure, it checks the second one.

Composer tries to remember these misses, but the result is only being used during the single script run, and then forgotten.

Assuming you state "NS":"src/", a class names NS\X will be searched in src/NS/X.php. If however you more likely have classes NS\X\A and NS\Y\B, you can define TWO longer prefixes NS\X and NS\Y instead of the single, shorter prefix NS. If you only host one single class inside the NS prefix, you could also use the whole classname as a prefix.

Always try to make the prefix as long and as precise as possible. They are namespaces for a reason, only one package should be responsible per namespace. Having two packages hosting classes for NS would make it hard to detect overlapping: What if two classes with the exact same name get created? With different namespaces per package, this cannot happen.

Sven
  • 69,403
  • 10
  • 107
  • 109
  • @Sven, imagine that I have the following: a set of standard interfaces, an abstract implementation of some methods of those interfaces, and a complete implementation based on the abstract one. They all relate to one "thing", they're directly related, but I want to keep them in separate packages - because I want to distribute/use them separately. Is this a valid reason to to what the OP is asking? – XedinUnknown Mar 13 '16 at 21:26
  • It's worth mentioning, that using optimized autoloading will mitigate the performance penalty mentioned at the beginning of the answer. See [this](https://github.com/composer/composer/issues/4605#issuecomment-156039043) GitHub comment. – Furgas Mar 07 '22 at 15:01