Resolving PHP composer dependency conflicts.
PHP's composer package manager is a fairly powerful piece of software backed by a large and active community of developers. With composer it's relatively easy to build up software like a jigsaw puzzle from any number of community contributed components. Many of these components are under active development, which is great because new functionality and bugfixes can easily be incorporated with a composer update.
However, this also means that dependency requirements also change over time, and you can easily end up in a situation where two modules depend on two different versions of the same module; dependency management hell.
The symptom of this is a screenful of obscure dependency conflict errors when running "composer update" or "composer install", like this:
How to avoid this problem?
This problem is almost always caused by using unspecific version numbers in your composer.json, or relying on "dev-master" for too many requirements. While it may work on the day you set up your project, as each project undergoes further development the chance increases that the head commit will introduce an incompatibility.
The only 100% sure way to avoid this is to use specific version tags for your requirements. By specifying exact version numbers, each time you run "composer update" you're getting the versions that you developed and tested against.
If you've already gone ahead and set up your requirements using dev-master or loose versioning (e.g. "~1.0.*"), you could manually work through your composer.json to resolve the version numbers by hand. That will take some time, but you will end up with a cleaner and more reliable set of requirements.
What if I don't have time for that?
Time is always of the essence, and your code needs to work today, and although it's not pretty, there is a way to work around most dependency conflicts using Inline Version Aliases.
An inline version alias lets you depend on a certain version number to satisfy the requirements of one module, and provide an alias so that another module is also satisfied.
{ "repositories": [ { "type": "vcs", "url": "https://github.com/you/monolog" } ], "require": { "symfony/monolog-bundle": "2.0", "monolog/monolog": "dev-bugfix as 1.0.x-dev" } }
In the above example from the composer docs, the "dev-bugfix" branch is the version that is installed with composer, however modules may also see it as "1.0.x-dev".
More often than not, this will let you continue with your "composer update" or "composer install", and there's a good chance you won't run into any further issues.
Final words...
Use caution. This technique should not be considered a fix. It's a quick workaround for sticky situations and tight deadlines.
Modules specify dependecies for a reason and there is a risk that by tricking a module into using a different version than it was built for, your code may break or have undesired behavior.
While this may help you get back up and running quickly so you can meet that deadline, specifying actual version numbers in your requirements is always going to be the safest way to manage dependencies with composer.
As always, happy coding!