Jump to content

Composer with different versions of PHP


NotionCommotion

Recommended Posts

php74 is installed as my primary php, but I am also working with a different framework that can only use php73 and set up a separate pool to deal with it.  Recently, my installed composer1 told me I should upgrade to composer2 and I did so, but then found that the previously mentioned other framework also doesn't work with composer2 but only composer1.

When updating a package with composer, sometimes I get composer errors or even worse no composer errors but PHP errors later on where classes don't exist, and I think it relates to using the wrong version of PHP (and maybe even composer).

Is it always required to consistently use composer with a single version of PHP?  Anything to worry about different versions of composer or will I just get a message.  Any other best practices?  Any issues how I set up composer below?

Thanks!

curl -sS https://getcomposer.org/installer | php
# or if desired, use resulting composer.phar as: $ php (or php73) composer.phar update/install/etc
chmod +x composer.phar
sudo mv composer.phar /usr/local/bin/composer
sudo ln -s /usr/local/bin/composer  /usr/local/bin/composer2

curl -sS https://getcomposer.org/installer | php73
chmod +x composer.phar
sudo mv composer.phar /usr/local/bin/composer2_73

php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php -r "if (hash_file('sha384', 'composer-setup.php') === '756890a4488ce9024fc62c56153228907f1545c228516cbf63f885e036d37e9a59d27d63f46af1d4d07ee0f76181c7d3') { echo 'Installer verified'; } else { echo 'Installer corrupt'; unlink('composer-setup.php'); } echo PHP_EOL;"

php composer-setup.php --version=1.10.19
chmod +x composer.phar
sudo mv composer.phar /usr/local/bin/composer1

php73 composer-setup.php --version=1.10.19
chmod +x composer.phar
sudo mv composer.phar /usr/local/bin/composer1_73

rm composer-setup.php

 

Link to comment
Share on other sites

/usr/local/bin/composer is going to be the same file regardless of whether `php` runs PHP 7.3 or 7.4.

Install Composer 1 and 2 to different files, then ln "composer" to 2 since that works with most everything you have. For the other project that doesn't work with it, always run "composer1" commands.

If you have errors with Composer then you'll need to post those.

Link to comment
Share on other sites

1 hour ago, requinix said:

/usr/local/bin/composer is going to be the same file regardless of whether `php` runs PHP 7.3 or 7.4.

Thanks requinix,

I was pretty sure I sometime got quirky/different results when running as PHP7.3 or 7.4.  Are you also saying that the following will make no difference?
 

$ php   composer.phar --update  #php7.4

$ php73 composer.phar --update

In hindsight, agree my proposed solution of executing  composer-setup.php with different PHP versions probably made no sense.  If executing the phar with different PHP versions does have an effect, maybe make to executables for each composer version

#!/usr/bin/env php
<?php
/*
 * This file is part of Composer.
 *

 

#!/usr/bin/env php73
<?php
/*
 * This file is part of Composer.
 *

 

Link to comment
Share on other sites

Unless you have some error messages that say otherwise,

Composer doesn't care. You can run it with PHP 7.3 or PHP 7.4, it'll do the same thing. The only thing that matters is (apparently) Composer 1 vs. Composer 2.
Saying that Composer 2 should be run by PHP 7.4 and Composer 1 should be run by PHP 7.3 is pointless. There's no difference.

Link to comment
Share on other sites

Guess I incorrectly thought the the composer.json file can contain logic which dictates which version of some package is installed based on the executing PHP version.

Good to know it doesn't and I can remove that variable when troubleshooting why something isn't working the way I hoped.

 

PS.  https://github.com/concrete5/composer/issues/34#issuecomment-696401142 and similar statements are what maybe made me think so.

Quote

It sounds like you might've installed composer dependencies with a different PHP version to the one you're using to install concrete5, try using the same php version for both

 

Edited by NotionCommotion
Added link to reference
Link to comment
Share on other sites

2 hours ago, NotionCommotion said:

Guess I incorrectly thought the the composer.json file can contain logic which dictates which version of some package is installed based on the executing PHP version.

Yes, it can do that. Is that fact relevant here?

Even if so, that still doesn't mean Composer 1/2 should be coupled to PHP 7.3/7.4. What it means is that you should be using the version of PHP necessary for the project. Just like how you would be using the version of Composer necessary for the project. But those are still two different things.

Link to comment
Share on other sites

2 hours ago, requinix said:

Yes, it can do that. Is that fact relevant here?

Even if so, that still doesn't mean Composer 1/2 should be coupled to PHP 7.3/7.4. What it means is that you should be using the version of PHP necessary for the project. Just like how you would be using the version of Composer necessary for the project. But those are still two different things.

Yes, if true, it might be relevant here.  If based on the given project, I need to use either PHP7.3 or PHP7.4 and either Composer 1 or Composer 2, then I need either:

  1. A composer1.phar and a composer2.phar and run them using either php (7.4) or php73.
  2. A composer 1 executable which uses PHP7.3, a composer 1 executable which uses PHP7.4, a composer 2 executable which uses PHP7.3, and a composer 2 executable which uses PHP7.4.

I prefer the second approach with the executables located in /user/local/bin instead of crating around all these composer phar files.

Am I missing something?

Link to comment
Share on other sites

I remember at one point that composer 2 wasn't compatible in some ways with earlier versions of php, but that doesn't appear to be the case at this point. However, if you absolutely need different versions of composer and want to do it easily, consider using docker.

Re-reading this thread I'm not sure the exact use case (it's late after a long day, so I may have just missed it) but it certainly seems like you're making things more complicated than they need to be.

Edited by maxxd
Link to comment
Share on other sites

What's important is that your development environment match your production environment, at least to the minor level.  If you do something like develop with PHP 7.4 but production runs PHP 7.3 then you might have issues.  The reason is that when you update your packages with composer it will calculate the dependencies based on the running PHP version (7.4 in the example) then save those dependencies to the composer.lock file.  When you then run composer install on production it will try and install the locked 7.4-based dependencies and potentially cause issues.

If you have different projects using different versions of PHP then you'll have to have those different versions of PHP available for your development environment as well and make sure you use the correct version when working on a project.  You don't (or at least shouldn't) need separate composer installs, just make sure you run it with the correct PHP version for that project.  A simple wrapper script for each project could be used to help with this.

If you don't want to deal with multiple PHP versions then an alternative solution is to fake your production platform using composer's config.platform option in your composer.json file:

{
   "config": {
      "platform": {
         "php": "7.3.0"
      }
   }
}

That tells composer to calculate the dependencies while assuming that the current PHP version is 7.3.0 rather than looking at what's actually running.   Whenever you update your production PHP version you'll need to update the version here to match.

Link to comment
Share on other sites

On 1/25/2021 at 5:31 PM, maxxd said:

I remember at one point that composer 2 wasn't compatible in some ways with earlier versions of php, but that doesn't appear to be the case at this point. However, if you absolutely need different versions of composer and want to do it easily, consider using docker.

Re-reading this thread I'm not sure the exact use case (it's late after a long day, so I may have just missed it) but it certainly seems like you're making things more complicated than they need to be.

Use case is building a plugin for an existing CMS.  The CMS and plugin are normally located remotely and the CMS "installs" the plugin.  The plugin is fine with PHP7.4, but when it passes a given symfony/etc object to the CMS, I get undefined method or interface violation errors.  I am uncertain whether the CMS uses the composer.json files directly and not just with composer.  Your docker idea might make sense.  Thanks

Link to comment
Share on other sites

On 1/25/2021 at 6:32 PM, kicken said:

What's important is that your development environment match your production environment, at least to the minor level.  If you do something like develop with PHP 7.4 but production runs PHP 7.3 then you might have issues.  The reason is that when you update your packages with composer it will calculate the dependencies based on the running PHP version (7.4 in the example) then save those dependencies to the composer.lock file.  When you then run composer install on production it will try and install the locked 7.4-based dependencies and potentially cause issues.

If you have different projects using different versions of PHP then you'll have to have those different versions of PHP available for your development environment as well and make sure you use the correct version when working on a project.  You don't (or at least shouldn't) need separate composer installs, just make sure you run it with the correct PHP version for that project.  A simple wrapper script for each project could be used to help with this.

If you don't want to deal with multiple PHP versions then an alternative solution is to fake your production platform using composer's config.platform option in your composer.json file:

That tells composer to calculate the dependencies while assuming that the current PHP version is 7.3.0 rather than looking at what's actually running.   Whenever you update your production PHP version you'll need to update the version here to match.

Thanks kicken,

Not sure if I really understood this part.  If I have both a composer.json and composer.lock file, composer install appears to install based on composer.lock and ignores composer.json and the composer.lock file will not be modified.  But then If I immediately afterwards perform a composer update, the dependencies "might" be changed resulting in a modified composer.lock file based on the PHP version.  If I perform a composer install, and don't have a composer.lock file, then composer will first give me a warning and then create a composer.lock file and install dependencies based on the composer.json file.  Seem accurate?

I had messed around with composer's config.platform option, but gave up.  Will look back into it.

Regarding your simple wrapper, are you talking about just a bash script to execute the composer.phar file with the appropriate PHP version?  If so, is this any different then editing the first line of the composer.phar file (i.e. #!/usr/bin/env php74 to #!/usr/bin/env php73) and making the file executable?

Link to comment
Share on other sites

composer install will install whatever the composer.lock file says to install.  If there is no composer.lock file then it behaves like composer update does.

composer update will parse the composer.json file and calculate all the dependencies based on the given requirements and current operating environment.  Once it determines what versions to install and verified the platform requirements it will write the final configuration to composer.lock so that it's quick and easy to install all those dependencies again if needed.

So if you move your project, including the composer.lock file, to a different platform and just run composer install then you could end up with compatibility issues because it might install the wrong dependencies for the platform.

The reason for doing things this way rather than just always resolving dependencies is so you can install a known-good set of dependencies.  If you just got the latest versions every time then 6 months from now when you want to install your application on a new server you might get an update version of some library that ends up not working rather than the working version you last tested with.   Guzzle/promises for example recently released a new minor version that has a bug which broke one of my hobby projects.  Had it been a real project being deployed somewhere it would have been very bad to have something like that happen.

 

3 hours ago, NotionCommotion said:

If so, is this any different then editing the first line of the composer.phar file

It's different in that you don't have to keep separate composer.phar files around.  You can just have one that is kept up to date but run it with the appropriate PHP version.  If you'd rather just have separate composer.phar files that's fine too.

 

  • Like 1
Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.