Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.Sign up
Add explicit possibility to selectively replace vendor classes #4732
Sometimes an upstream class in vendor is not extensible enough with conventional language constructs (e.g. it's
Currently this is possible because composer's class loader prefers
Composer as the central authority for loading classes brings the great opportunity to replace selectively vendor classes completely. Let's specify an explicit mechanism to define a sequence of class paths.
The detailed specification should come with this discussion. For a starter we could discuss a simple
I can understand your reluctance and I would also not promote that feature highly. However I disagree with zero need. Imagine you would depend on a third party library which you want to behave slightly differently (e.g. you want to log a message). Sometimes the author didn't provide extension points which would enable this. All your friendly questions will not help in this case, as the offending class might be final or is instantiated as an implementation detail.
Forking and patching the class in the fork is a viable option, but then again why do I need to fork in the first place, if technically replacing the offending class is possible?
Thank you for that suggestion. I'm aware of PHP extensions which would do the job (e.g. runkit to name a further one). This proposal is specifically targeted to use plain PHP's autoload mechanism for most portability.
Well, I can see that until now there's no support for this idea. I'm really Sorry for not coming up with any new use cases, but elaborating on the existing ones:
Mocks for final classes
Surprisingly I see
No suitable extension point
This is actually more a generalization of the
Won't be fixed
Let me present my current use case: I'm the author of php-mock which is a mocking tool targeted at PHP's built-in functions. As I don't want to pollute the cognitive load of developers I do offer integrations for well known existing frameworks. One of them will be php-mock-prophecy. However there's one offending line of code in upstream which prevents me from implementing prophecies for built-ins which use pass-by-reference (e.g.
Well, technically I guess this can already be done. If Composer detects a duplicate class (namespace+classname), it will only load one of the available choices. If you simply make sure your class is detected before the one from the other library, you should be good to go. Not sure how you can make sure of that though... :d
I've been trying to make this work as well. I thought that Composer loaded dependencies in order: classpath, psr-0, psr-4, but recently (with a composer update?) I started getting "Ambiguous class resolution" warnings, and the vendor class (psr-4) was getting loaded instead of my class (defined in classpath). I think we just need some consistency here.
My particular use-case is that the vendor library I'm using calls "new Someclass" instead of injecting it, and that class has a critical error. I would have to overload so many different classes in the library to get it to work, that I might as well just maintain my own fork. I realise this isn't the best approach, but sometimes we just need to move faster than upstream and maintaining a ton of independent forks is an unnecessary nuisance when it's something this simple.
Edit: I was able to solve my particular case by excluding the vendor class, adding it to autoload.exclude-from-class-map.