phpdependenciescomposer-phporganization

Installing multiple versions of a composer package


I have been thrusted into the "wonderful" world of Composer because PHP libraries are starting to not offer an easy way to download and install the source code manually.

We have a very big system with decades worth of code so some inevitable things are slated to occur such as:

I am going to pick on Google/Cloud since it has several dependencies such as guzzlehttp.

If I do:

cd /libraries/composer/google/cloud/0.179.0
composer require google/cloud:0.179.0

cd /libraries/composer/different_vendor/package/version
composer require different_vendor/package:version
# pretend this different vendor requires a version of guzzlehttp which is incompatible with google/cloud

cd /libraries/composer/guzzlehttp/guzzle/7.4.2    
composer require guzzlehttp/guzzle:7.4.2

Then would I have an issue writing code such as this?

<?php
require_once( '/libraries/composer/google/cloud/0.179.0/vendor/autoload.php' );
require_once( '/libraries/composer/different_vendor/package/version/vendor/autoload.php' );
require_once( '/libraries/composer/guzzlehttp/guzzle/7.4.2/vendor/autoload.php' );

If I have a need for google/cloud in one micro-app and guzzle in another then do I need to import google/cloud into the app that just needs guzzle?

I'm just trying to wrap my head around the benefits of Composer because all of the blogs mindlessly say "jUsT uSe ComPOsEr". I can see how composer is useful for one-off set-it-and-forget-it webapps which is presumably running on a dedicated server but that is far from our ecosystem; a website which serves public pages and various micro-apps requested by departments from a single domain.

I can definitely see why the code below would be a problem but I don't envision such a need ever occurring:

<?php
require_once( '/libraries/composer/google/cloud/0.178.0/vendor/autoload.php' );
require_once( '/libraries/composer/google/cloud/0.179.0/vendor/autoload.php' );

Solution

  • In short, no, you cannot use composer to install multiple versions of a dependency within the same project. The entire point of composer is to look at all the dependencies for a given project and install a version that will work given that combination of dependencies.

    What I am gathering from your phrasing and examples is that you are managing a bank of dependencies separately from the actual projects. Composer is designed to maintain separate dependencies per project, not to manually manage dependencies in a shared folder used by all projects.

    So, if you have 30 projects, you should have a separate composer.json file in the root of each project, and that will control your dependencies for that project, but each project itself could have different sets of dependencies. This, for example, allows you to migrate one project at a time to a new major php version and/or new server.

    If you have libraries of code that you have created that you reuse across your own projects, then ideally you would turn your own shared library into a private composer package that you can then install as a dependency in the composer.json of each of your 30 projects that uses it. At this point, you can have separate versions of your own package, and the dependencies of things like the google api can vary between separate versions of your own package, and each of the 30 projects can then require the version of your package best suited for that project.