Po pridaní podpory pre PHP 8.0 oznámil Arch v januári, že ponechá staršie balíčky PHP7 dostupné. PHP scéne som sa nevenoval, ale nedávno som niečo potreboval otestovať.

Test očividne vyžadoval hlavný balíček php, teraz vo verzii 8.0, a druhou pevnou požiadavkou je composer, správca balíčkov pre PHP.

sudo pacman -S php composer

Pokus o spustenie composer install v koreňovom priečinku softvéru zobrazil nasledujúcu chybu:

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.

Chyba znamená, že to, čo som testoval, bolo napísané pre PHP7, ale mal som už nainštalovaný nekompatibilný PHP8.

Starší balíček PHP7 #

Pomyslel som si, žiadny problém. Stačí nainštalovať starší php7 hlavný balíček spomínaný v správe a všetko bude v poriadku.

sudo pacman -S php7

Správu som nečítal dôkladne, takže som očakával, že pacman mi ponúkne odstránenie balíčka php pri inštalácii php7, keďže by mohli byť v konflikte. To sa nestalo. Balíček php7 sa nainštaloval bez problémov, pokojne žijúc vedľa základného balíčka php. Stále bez čítania správy som začal pátrať:

pkgfile --list --binaries php7

Áno, teraz je zrejmé, prečo nedošlo ku konfliktu súborov, konkrétne binárky /usr/bin/php:

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

Balíčky sú postavené tak, aby si navzájom neprekážali. Správa to dokonca explicitne uvádza:

PHP 7 binaries and configuration have the “7” suffix:

  • /usr/bin/php -> /usr/bin/php7
  • /etc/php -> /etc/php7

Čo teda robiť?

Riešenie konfliktov súborov #

Prvým zjavným spôsobom bolo vytvoriť symbolický odkaz, keďže som nebol istý, či môžem prinútiť všetok softvér, ktorý som práve testoval a o ktorom som nič nevedel, používať binárku php7 namiesto bežného php, ktoré určite očakával.

sudo ln -s /usr/bin/php7 /usr/bin/php

Nie tak rýchlo, alebo vlastnými slovami terminálu:

ln: failed to create symbolic link '/usr/bin/php': File exists

Takže riešenia, ktoré mi v tú chvíľu napadli:

  1. Ponechať všetky balíčky, odstrániť len /usr/bin/php a vytvoriť symbolický odkaz
  2. Odstrániť balíček php a potom vytvoriť symbolický odkaz
  3. Nejaká mágia s premennou prostredia PATH

Tretiu možnosť som nepovažoval za príliš dôležitú pre krátky test, do ktorého mohli byť zapojení rôzni systémoví používatelia. Riešenie cez PATH by mohlo viesť aj k ťažko vysvetliteľným chybám a musel som to najprv rozbehať a experimentovať neskôr, takže som uvažoval o symbolických odkazoch.

Hoci nemám rád vytváranie symbolických odkazov medzi systémovými súbormi, stále som nenašiel absolútne najlepšiu praktiku, ktorá by fungovala hneď v každom možnom scenári, takže druhá možnosť sa zdala byť menším zlom z tých dvoch.

sudo pacman -Rnc php

Nie, toto so sebou stiahne aj composer.

Problematická závislosť composer #

Pokus o preinštalovanie composer privádza php ako závislosť, takže tieto dva sa pravdepodobne nerozdelia. Existujú však možnosti:

  • Odstrániť závislosť z PKGBUILD composeru
  • Nainštalovať composer bez závislostí

Pozrime sa na obe.

Odstránenie závislosti z PKGBUILD #

Závislosť php je uvedená s kľúčovým slovom depends= v PKGBUILD. Musíme ju odtiaľ odstrániť, znovu zostaviť balíček a nainštalovať všetko. Celý príkaz by mohol vyzerať takto:

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

Nie som si úplne istý, čo sa stane počas aktualizácie. Vyzerá to dosť chaoticky, ale funguje.

Inštalácia composer bez závislostí #

Pacman sám ponúka ďalšiu možnosť, jej použitie je však veľmi odrádzané, takže použite len ak akceptujete riziko, že váš systém sa môže kvôli tomu rozbiť:

sudo pacman -Sdd package_name

Použitie parametra -dd pri inštalácii balíčka nenainštaluje jeho závislosti. Celá sada príkazov by potom vyzerala takto:

sudo pacman -S php7
sudo ln -s /usr/bin/php7 /usr/bin/php
sudo pacman -Sdd composer
composer --version

Aj ja musím ešte plne pochopiť riziká spojené s týmto riešením tohto problému so závislosťami, takže používajte s opatrnosťou.

Záver #

Po inštalácii balíčka php7 a potom composer bez závislosti php, ktorá by automaticky stiahla verziu 8.0, a po vytvorení symbolického odkazu na binárku teraz composer install v softvéri závislom od PHP7 funguje bez sťažností. Treba pochopiť dlhodobé dôsledky týchto krokov, ale zatiaľ to vyzerá dobre. Rád by som videl, ako to riešia rôzni ľudia.