After adding support for PHP 8.0, Arch news reported they are keeping legacy PHP7 packages available back in January. I was quite out of PHP scene for now, but recently, I had to test something.
The test obviously required the php core package, now the version 8.0 and a second hard requirement is a composer, a PHP's package manager.
sudo pacman -S php composer
Trying to run composer install
in the software's root folder shown the
following error:
Your lock file does not contain a compatible set of packages. Please run composer update.
Problem 1
- Root composer.json requires php ^7.3.0 but your php version (8.0.7) does not satisfy that requirement.
The error means that, what I was testing was written for PHP7, but I had an incompatible PHP8 already.
PHP7 legacy package
I thought, no problem. Just install the legacy php7 core package mentioned in the news post and everything will be alright.
sudo pacman -S php7
I did not read the news post thoroughly so I was expecting that the pacman
will offer me to remove the php
package when installing the php7
package, assuming they would be in conflict. This did not happen. The
php7
package installed gracefully, living happily alongside the base
php
package. Still not reading the post, I started poking around:
pkgfile --list --binaries php7
Yeah, it is obvious now why there was no conflicting files, specifically
the /usr/bin/php
binary:
extra/php7 /usr/bin/phar7
extra/php7 /usr/bin/phar7.phar
extra/php7 /usr/bin/php-config7
extra/php7 /usr/bin/php7
extra/php7 /usr/bin/phpize7
The packages are built in such a way, they do not collide with each other. The post even states that specifically:
PHP 7 binaries and configuration have the "7" suffix:
- /usr/bin/php -> /usr/bin/php7
- /etc/php -> /etc/php7
- ...
What to do now?
Solving file conflicts
The first obvious way to introduce the symlink, as I was not sure if I
could force all the software I was just trying and knew nothing about use
php7
binary instead of just php
it surely expected.
sudo ln -s /usr/bin/php7 /usr/bin/php
Not so fast, or in a terminal's own words:
ln: failed to create symbolic link '/usr/bin/php': File exists
So there were some solutions that I came up with that second:
- Keeping all packages, remove just the
/usr/bin/php
and do the symlink - Remove the
php
package and then do a symlink - Do some
PATH
environment variable magic
I did not consider the third option too vital for a short test that might
even involve different system users. Making this work by changing PATH
could also lead to some hard to explain errors and I had to make it run
first, experiment later, so I considered symlinks.
Even though I do not like symlinking around the system files, I still did not find an absolutely best practice that would work out of the box in every possible scenario, so the second option seemed like a lesser of the two evils.
sudo pacman -Rnc php
No, this takes composer down with it as well.
Problematic composer dependency
Trying to install composer
back brings the php
as a dependency, so
these two are unlikely to part ways. There are options, however:
- Removing the dependency from the composer's PKGBUILD
- Install composer without dependencies
Let's explore both.
Removing the dependency from the PKGBUILD
The php
dependency is mentioned with keyword depends=
in the
PKGBUILD.
We have to remove it from there, rebuild the package and install
everything. The full command could look like this:
sudo pacman -S php7
sudo ln -s /usr/bin/php7 /usr/bin/php
yay -G composer # download the PKGBUILD file only
cd composer
sed "10s/'php'//" -i PKGBUILD
makepkg -sri
composer --version
Not entirely sure what happens during the upgrade, though. Looks very messy, but works.
Installing composer without dependencies
Pacman itself offers another option, but it's use is very discouraged, so use only when accepting the risk, that your system might break due to this:
sudo pacman -Sdd package_name
Using the -dd
parameter while installing a package does not install it's
dependencies. The full set of commands would then look like this:
sudo pacman -S php7
sudo ln -s /usr/bin/php7 /usr/bin/php
sudo pacman -Sdd composer
composer --version
Even I still have to fully understand the risks involved of solving this dependency problem like this, so use with caution.
Conclusion
After installing a php7
package and then composer
without the php
dependency, which automatically pulled version 8.0, symlinking the binary,
the composer install
in the software relying on PHP7 now works without
complains. Have to understand the long-term consequences of this actions,
but so far, so good. Definitely would love to see how different people
solve this.