PhpBrew. Менеджер версий PHP. (+ установка и использование в Ubuntu 13.10)

в 18:27, , рубрики: php, Убунтариум

Лирическое №1

PHP неуклонно взрослеет и обзаводится различными полезными дополнениями и некоторые из них уже ну совсем как у старших (хотя слово «младших» во многих случаях подойдет лучше).

В этом ключе стоит, например, вспомнить такие замечательные вещи как менеджер зависимостей composer, встроенный веб-сервер, появление namespace'ов и замыканий.

Сложилось так, что в качестве рабочей OS у меня установлена последняя версия Ubuntu (13.10). Долгое время я довольствовался последней стабильной версией PHP из репозиториев (видимо везло), но тут по работе пришел проект на 5.3 (а то и 5.2, но под 5.3 завелся), который никак не хотел стартовать на последней 5.5.3, что из официальных репозиториев и я было опечалился (уже имеется опыт установки неактуального PHP на Ubuntu, хоть и успешный, но весьма грустный), но потом вспомнил ruby и rvm.io и решил провести небольшое исследование. В итоге коллега подсказал озвученную в заголовке вещь.

Конец лирического. К фактам.

Если вкратце – единственное назначение phpbrew – возможность использовать разные версии PHP на одной машине. Быстро, просто, практически без танцев с народными музыкальными инструментами. (не продакшен, не параллельная работа, но мгновенное переключение между версиями при разработке).


Чтобы не растекаться мыслью по древу приведу (плохо) переведенную выдержку из официального readme:

phpbrew способен собрать и установить несколько различных версий PHP в домашнюю директорию текущего пользователя.
Также phpbrew помогает управлять переменными окружения – при помощи команд use и switch можно легко переключаться между версиями PHP.

Что умеет phpbrew:

  • Собирать PHP с различными расширениями (PDO, mysql, sqlite, debug… и т.д.)
  • Собирать модули для Apache (для каждой версии по модулю)
  • Собирать и устанавливать PHP прямо в домашнюю директорию, а значит – не требовать root права для работы (тут с оговорками – прим. переводчика, см. ниже)
  • Легко переключать версии PHP при помощи простых команд, интегрированных в оболочки bash/zsh
  • Автоматически определять фичи (честно говоря не понял о чем это — прим. переводчика)
  • Легко устанавливать расширения в текущий environment
  • Устанавливать несколько версий PHP в систему
  • Итак, короткая инструкция по установке и использованию под Ubuntu 13.10 (Хотя в readme все описано предельно понятно, так что практически репост) с обзором нескольких подводных камней.

Cтоит добавить что не умеет он автоматически интегрироваться в nginx.

Установка

1) Установить зависимости согласно официальному документу с requirements

# apt-get build-dep php5
# apt-get install -y php5 php5-dev php-pear autoconf automake curl build-essential libxslt1-dev re2c libxml2 libxml2-dev php5-cli bison libbz2-dev libreadline-dev
# apt-get install -y libfreetype6 libfreetype6-dev libpng12-0 libpng12-dev libjpeg-dev
# libjpeg8-dev libjpeg8  libgd-dev libgd3 libxpm4
# apt-get install -y libssl-dev openssl
# apt-get install -y gettext libgettextpo-dev libgettextpo0
# apt-get install -y libicu48 libicu-dev
# apt-get install -y libmhash-dev libmhash2
# apt-get install -y libmcrypt-dev libmcrypt4
# apt-get install -y mysql-server mysql-client libmysqlclient-dev libmysqld-dev

Скорее всего вам не понадобятся ВСЕ эти зависимости, поэтому имеет смысл установить минимальный требуемый для сборки чистого PHP набор, а дальше ориентироваться на сообщения PHP'шого configure, который все равно будет вызываться для проверке соответствия системы требованиям.

2) Устанавливаем собственно phpbrew, все по той же инструкции

$ cd /tmp/
$ curl -O https://raw.github.com/c9s/phpbrew/master/phpbrew
$ chmod +x phpbrew
$ sudo cp phpbrew /usr/bin/phpbrew

3) По-прежнему по инструкции, инициализация

$ phpbrew init

4) Добавить следующую строку в .bashrc (или .zhrc)

source ~/.phpbrew/bashrc

После этого нужно закрыть и снова открыть консоль (ну или просто сделать logout/login, это по ситуации) чтобы новые команды в bashrc проинициализировались. Или самостоятельно запустить в консоли

$ source ~/.phpbrew/bashrc

Готово. Можно пользоваться.

Настройка

Информация из этого пункта также доступна в официальном readme. И часть ее в официальном гайде troubleshooting.

$ phpbrew known

Покажет список доступных версий (есть версии и старше – для них к команде нужно добавить ключ –old)

$ phpbrew variants 

Покажет список доступных вариантов для установки PHP. (по факту — расширения с которыми PHP будет собираться)
phpbrew install [version] [variants] установит PHP нужной версии с указанными расширениями. Варианты перечисляются через пробел, каждый начинается с “+”. Например команда:

$ phpbrew install 5.3.28 +default

Загрузит и соберет PHP 5.3.28 с базовым набором компонентов (различные zip, json, mbstring и прочее повседневно-утилитарное)

$ phpbrew install 5.3.28 +default +dbs +icu +intl

* стоит отметить что (скорее всего так у вас ничего не соберется, см. раздел Troubleshooting этой статьи.

Загрузит и соберет PHP 5.3.28 с базовым набором компонентов а также с icu и intl (intl вполне логично не соберется без ICU, а без intl почему-то не собирается PHP 5.3 на Ubuntu)

Тут лирическое №2, по поводу root:

Чтобы добавить автоматически собранный модуль для apache2 нужно команде phpbrew install передать вариант +apxs2. Но.
Проблема в том, что Apache и его модули находятся не в пользовательских директориях, а посему phpbrew просто не сможет свой модуль никуда положить и упадет при попытках сделать это.

Workaround'а два – оба вполне официально предложены автором в разделе coockbook и оба мне не нравятся:
1) Устанавливать phpbrew и все сопутствующие штуки не в домашнюю директорию, а system-wide (все почти так же, только под root) – получается что как-то противоречит изначальной идеологии проекта. Подробно расписан в coockbook.
2) Временно разрешить себе запись в нужные директории.Потом не забыть запретить обратно. Ну это просто как-то неправильно.

Для Ubuntu 13.10 и apache 2.4.6 нужными будут /usr/lib/apache2/modules/ и /etc/apache2/mods-available/

# chmod a+w /usr/lib/apache2/modules/
# chmod a+w /etc/apache2/mods-available/

После этих подготовительных процедур таки ставим PHP 5.3.28 с базовым набором компонентов, с модулем apache, а также с icu и intl:

$ phpbrew install 5.3.28 +default +dbs +apxs2  +icu +intl 

Теперь проверим, что получилось:

$ php -v 
PHP 5.5.3-1ubuntu2.1 (cli) (built: Dec 12 2013 04:24:35)
$ phpbrew use php-5.3.28 
$ php -v 
PHP 5.3.28 (cli) (built: Jan 29 2014 00:55:42) 

Перезагрузим apache2 и проверим его:

# service apache2 restart

PhpBrew. Менеджер версий PHP. (+ установка и использование в Ubuntu 13.10)

Добавим еще одну версию точно таким же способом:

$ phpbrew install 5.5.8 +default +apxs2 +dbs +icu +intl 
$ phpbrew use php-5.5.8 
$ php -v 
PHP 5.5.8 (cli) (built: Jan 29 2014 01:53:33)

Еще раз перезагрузим apache2 и проверим:

PhpBrew. Менеджер версий PHP. (+ установка и использование в Ubuntu 13.10)

Все готово, осталось прибрать хвосты. Возвращаем доступы к системным директориям apache в нормальное состояние и передаем владение собранными модулями root'у (ну чтобы не выбивались из общего потока):

# chmod a-w /usr/lib/apache2/modules/
# chmod a-w /etc/apache2/mods-available/
# chown root:root /usr/lib/apache2/modules/libphp5.*

Установка расширений

Еще один момент — установка расширений. Все проще простого — phpbrew интегрирован с PEAR.
Просто используйте команду:

$ phpbrew ext install [extension_name]
И дальше phpbrew сделает все сам. Скачает расширение, соберет его и активирует для активной версии php. Например:

$ phpbrew ext install apc

или:

$ phpbrew etx install xdebug

Переключение версий

Собственно далее, если нужно переключить версию CLI – используем phpbrew use [version] (или phpbrew switch [version]), если же нужно переключить версию для apache2 – ищем где у apache происходит загрузка нашего модуля (в случае Apache 2.4.6 и Ubuntu 13.10 это будет /etc/apache2/mods-available/php5.load (или симлинк в mods-enabled), открываем его любым текстовым редактором и в строчке (например):

LoadModule php5_module        /usr/lib/apache2/modules/libphp5.5.8.so

меняем версию на нужную нам (и, конечно, установленную в системе, например)

LoadModule php5_module        /usr/lib/apache2/modules/libphp5.3.28.so

Перезагружаем apache и:

PhpBrew. Менеджер версий PHP. (+ установка и использование в Ubuntu 13.10)
(да, вы правы, на самом деле этот тот же самый скриншот, что и в первом случае, тем не менее он отражает объективную действительность.)

Альтернативы:

Помимо этого решения существуют еще (как минимум) phpenv и php-version. С ними предлагаю ознакомиться самостоятельно (буде возникнет такая необходимость)

Troubleshooting


В общем-то все есть в официальном гайде. Два момента, с которыми столкнулся лично:

1) Проверка config жалуется на отсутствующий libpcre.(a|so) и ничего не собирает под таким неблаговидным предлогом.

Это не проблема phpbrew, эта проблема лежит на стыке ubuntu и php — php и не пытается искать библиотеки по нестандартным путям, Ubuntu, зачем-то держит их в не совсем стандартном расположении.

К счастью phpbrew позволяет при помощи ключа — передавать в make дополнительные параметры. Вам остается только найти эти библиотеки и скормить их команде phpbrew install.

Для Ubuntu 13.10 (скорее всего для всех основанных на Debian дистрибутивов) реальная команда для установки php в варианте из статьи будет выглядеть так:

$ phpbrew install 5.3.28 +default +dbs +apxs2  +icu +intl --  --with-libdir=lib/x86_64-linux-gnulibpcre.a

2) При сборке php 5.3 появляется ошибка вида:

libtool: unrecognized option `-export-dynamic' 
Try `libtool --help' for more information.

Баг специфичный именно для 5.3. Просто добавьте к phpbrew install варианты "+icu +intl" (как и делается везде в рамках этой статьи).

Еще раз официальные источники:

  1. phpbrew: github.com/c9s/phpbrew
  2. Readme: github.com/c9s/phpbrew/blob/master/README.md
  3. Troubleshooting: github.com/c9s/phpbrew/wiki/Troubleshooting
  4. Coockbook: github.com/c9s/phpbrew/wiki/Cookbook

Автор: Gugic

Источник

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js