Strategy to override a class in a library installed with Composer
In composer.json, under ["autoload"]["psr-4"], add an entry with namespace as the key and path as the value:
{
"autoload": {
"psr-4": {
"BuggyVendor\\Namespace\\": "myfixes/BuggyVendor/Namespace"
}
}
}
Copy files you want to override under that path (keeping sub-namespace directory structure) and edit them there. They will be picked in preference to the library package's original "classpath". It would seem that namespace->path mappings added to composer.json in this manner are considered before those added by required packages. Note: I just tried it and it worked, though I don't know if it is an intended feature or what possible gotchas are.
EDIT: found a gotcha. Sometimes when you subsequently require another package with composer require vendor/package
, you will "lose" the override. If this happens, you must issue composer dump-autoload
manually. This will restore the correct autoload order honoring your override.
Adding these last 2 lines to the autoload
section of my composer.json
is what worked for me when I wanted to override just one file within the vendors
directory:
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
},
"exclude-from-classmap": ["vendor/somepackagehere/blah/Something.php"],
"files": ["app/Overrides/Something.php"]
},
Remember that the namespace within app/Overrides/Something.php
needs to match whatever the original was in vendor/somepackagehere/blah/Something.php
.
Remember to run composer dump-autoload
after editing the composer.json
.
Docs: https://getcomposer.org/doc/04-schema.md#files