Жонглюємо версіями PHP в системі

Проблема " хочу нову версію %software% на моєму стареньк… стабільному Debian/CentOS..." так само стара, як *nix-світ. Способів домогтися бажаного вистачає. Є маса рішень як притягнути в систему декілька версій одного і того ж софту. Але далі хочеться не просто мати ще одну версію, але і керувати тим, яка з версій доступна в системі за умовчанням, для конкретних додатків або користувачів.
Що робити, якщо хочеться змінити системну версію PHP на одну з кастомних збірок? Давайте відштовхуватися від того, що у вас на сервері вже встановлено декілька версій PHP і ви хочете, щоб в консолі команда php була конкретної версії, що відрізняється від тієї, що йшла з системою. У цій статті я розповім, як правильно налаштувати, щоб не було проблем з майбутніми пакетними оновленнями.

В якості прикладу візьмемо сервер на CentOS 7, де встановлено рідний PHP:
# php -v
PHP 5.4.16 (cli) (built: May 12 2016 13:45:17)
Copyright © 1997-2013 The PHP Group
Zend Engine v2.4.0, Copyright © 1998-2013 Zend Technologies
with the ionCube PHP Loader (enabled) + Intrusion Protection from ioncube24.com (unconfigured) v5.0.12, Copyright © 2002-2015, by ionCube Ltd.

Також на сервері встановлений наш Plesk з парою своїх збірок PHP:
# rpm -qa | grep plesk-php.*-release
plesk-php56-release-5.6.22-centos7.16052711.x86_64
plesk-php70-release-7.0.7-centos7.16052710.x86_64

Припустимо, ми хочемо перемкнути систему на використання PHP 5.6 за замовчуванням (перемикати глобально PHP з версії 5.4 на 7 як-то сс… страшно — чого-то в системі може поплохеть від такого). Бинарь PHP 5.6 лежить у нас тут:
# /opt/plesk/php/5.6/bin/php -v
PHP 5.6.22 (cli) (built: May 27 2016 11:45:28)
Copyright © 1997-2016 The PHP Group
Zend Engine v2.6.0, Copyright © 1998-2016 Zend Technologies
with the ionCube PHP Loader (enabled) + Intrusion Protection from ioncube24.com (unconfigured) v5.0.18, Copyright © 2002-2015, by ionCube Ltd.
with Zend OPcache v7.0.6-dev, Copyright © 1999-2016, by Zend Technologies

Як же зробити так, щоб система використовувала цю потрібну нам, версію PHP?
Спочатку подивимося на системну змінну PATH
# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin

У ній перераховано список директорій, в яких шукаються програми по імені. Головний нюанс — пошук в директоріях відбувається послідовно і використовується перший знайдений результат. Поточний шлях до поточного бінарника PHP ми можемо побачити з допомогою команди:
# which php
/usr/bin/php

Як видно з
PATH
,
/usr/local/bin
у списку раніше, ніж
/usr/bin
. Значить, якщо ми помістимо посилання на альтернативну версію PHP «раніше»,
/usr/local/bin
, то саме вона й буде використовуватися при виклику команди
php
замість
/usr/bin/php
. Ми можемо створити цю посилання руками (і навіть буде працювати), але правильніше використовувати спеціально створену для цих цілей утиліту
update-alternatives
(в CentOS це просто
alternatives
, але є симлинка
update-alternatives
, тому далі будемо оперувати саме цією командою, як універсальної для Debian/Ubuntu/CentOS/і т. д.).
Тепер, давайте зареєструємо всі доступні версії PHP за допомогою цієї команди:
# update-alternatives --install /usr/local/bin/php php /opt/plesk/php/5.6/bin/php 10
# update-alternatives --install /usr/local/bin/php php /opt/plesk/php/7.0/bin/php 20
# update-alternatives --install /usr/local/bin/php php /usr/bin/php 30

Цифри 10, 20 і 30 — це пріоритет. Він працює для автоматичного вибору, якщо адміністратор сам не вибрав конкретну версію. Найбільше число визначає вибір "за замовчуванням".
Перевіримо, що
php
тепер вказує на створену командою симлінку:
# update-alternatives --list | grep php
php auto /usr/bin/php

# update-alternatives --display php
php - status is auto.
link currently points to /usr/bin/php
/opt/plesk/php/5.6/bin/php - priority 10
/opt/plesk/php/7.0/bin/php - priority 20
/usr/bin/php - priority 30
Current `best' version is /usr/bin/php.

Давайте розберемося, що ж
update-alternatives
зробила для нас:
# which php
/usr/local/bin/php
# ls -l /usr/local/bin/php
lrwxrwxrwx. 1 root root 21 Jul 2 10:03 /usr/local/bin/php -> /etc/alternatives/php
# ls -l /etc/alternatives/php
lrwxrwxrwx. 1 root root 26 Jul 2 10:03 /etc/alternatives/php -> /usr/bin/php

Як видно, вона створила ланцюжок симлинок і тепер на вимогу просто змінює проміжну симлінку на потрібний нам бинарь.
# php -v
PHP 5.4.16 (cli) (built: May 12 2016 13:45:17)
...

тобто, ми успішно налаштували групу PHP
update-alternatives
, де за замовчуванням в автоматичному режимі обраний системний PHP. Зараз у нас є можливість переключити команду PHP на будь-яку іншу версію..
Давайте перемкнемося на PHP версії 5.6, яка йде в поставці з Plesk'ом:
# update-alternatives --config php

There are 3 programs which provide 'php'.

Selection Command
-----------------------------------------------
1 /opt/plesk/php/5.6/bin/php
2 /opt/plesk/php/7.0/bin/php
*+ 3 /usr/bin/php

Enter to keep the current selection[+], or type selection number: 1

Перевіряємо, що перемикання сталося:
# php -v
PHP 5.6.22 (cli) (built: May 27 2016 11:45:28)
...
# update-alternatives --display php
php - status is manual.
link currently points to /opt/plesk/php/5.6/bin/php
... 

Все відмінно працює. Тепер у системі використовується потрібна нам версія PHP і я не боюся, що ця настройка злетить при наступних пакетних оновлення.
З допомогою
update-alternatives
можна вибирати не тільки версію PHP, але і багато інших речей, наприклад різні версії
phpunit
або редактор за умовчанням в системі. Цей підхід є універсальним для різних систем. Не винаходячи свого велосипеда, використовуючи існуючі інструменти, ви можете бути впевненим, що не влаштували для ваших колег квесту «Ну чому воно так працює?!». Налаштуйте свою систему правильно.
p.s. Запрошую пофлеймить про
phpenv
в коментарі :)
Джерело: Хабрахабр

0 коментарів

Тільки зареєстровані та авторизовані користувачі можуть залишати коментарі.