Лирическое №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 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 и проверим:
Все готово, осталось прибрать хвосты. Возвращаем доступы к системным директориям 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 и:
(да, вы правы, на самом деле этот тот же самый скриншот, что и в первом случае, тем не менее он отражает объективную действительность.)
Альтернативы:
Помимо этого решения существуют еще (как минимум) 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=/usr/lib/x86_64-linux-gnu/
2) При сборке php 5.3 появляется ошибка вида:
libtool: unrecognized option `-export-dynamic'
Try `libtool --help' for more information.
Баг специфичный именно для 5.3. Просто добавьте к phpbrew install варианты "+icu +intl" (как и делается везде в рамках этой статьи).
Еще раз официальные источники:
- phpbrew: github.com/c9s/phpbrew
- Readme: github.com/c9s/phpbrew/blob/master/README.md
- Troubleshooting: github.com/c9s/phpbrew/wiki/Troubleshooting
- Coockbook: github.com/c9s/phpbrew/wiki/Cookbook