Программист руками
0,0
рейтинг
5 февраля 2014 в 22:27

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

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 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" (как и делается везде в рамках этой статьи).

Еще раз официальные источники:
  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
карма
74,2
рейтинг 0,0
Программист руками
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (14)

  • +2
    Под CloudLinux есть менеджер php называется cl-selector, так-же позволяет использовать и переключать разные версии php, включать/выключать отдельные модули для каждого пользователя (полезно на шаред хостинге).
  • +3
    Без использования менеджеров версий можно под той же ubuntu скомпилировать различные версии php и повесить php-fpm на разные порты, в итоге работают всегда и, главное, параллельно. Почему этот подход не был использован при разработке данного менеджера?
    • +1
      А как решается вопрос с консольным интерпретатором? Алиасы, симлинки?
  • +3
    Я под это дело на тестовом сервере, с помощью docker, линуксовые контейнеры приспособил. Но описанный подход имхо на рабочей машине удобней.
    В gentoo, как я помню, такое вроде стандартными средствами решалось.
  • +1
    И видимо он не должен ничего про nginx уметь. Просто рестартуете fpm и все будет работать как надо.
    А вот с fpm он что-то умеет делать github.com/c9s/phpbrew#php-fpm
  • +2
    Использую сервер в виртуальной машине с gentoo для этой цели, правда установить можно только различные мажорные версии (5.5, 5.4, 5.3,...)

    Команда: eselect

    например:

    eselect php list fpm
    


    Выдаст чтото вроде:
      [1]   php5.3 *
      [2]   php5.4
      [3]   php5.5
    
  • +1
    Столкнулся с такой же проблемой, когда недавно решил пересесть на Ubuntu. Пока что моих знаний хватило только на то, чтобы поставить два разных xampp с необходимыми мне вверсиями php.
    Минусы:
    — нужно настраивать каждый инстанс xampp отдельно, хосты, php.ini и т.д.
    — кроме разных версий php, там еще и разные MySQL, а соответственно и разные базы.
    — не получится параллельной работы.
    Лично меня такой расклад устраивает. Уверен, что можно все сделать иначе и по фен-шую, но пока что смог только так.

    Плюсы:
    Без проблем заводится и взлетает по отдельности любое количество версий php: 5.2, 5.3, 5.4 и т.д. и не требуется никаких виртуальных машин.
    Учитывая что мне не нужна параллельная работа одновременно в нескольких версиях php, то все это дело меня более чем устраивает.

    И самое главное, что процедура настройки посильна фактически любому новичку в Ubuntu.
  • +1
    после упоминания в названии «brew» почему-то в голову сразу пришла макось. Не знаю не знаю.
    Да и вообще упоминания apache и ubuntu как-то не в тему разных версий php на одной машине…
  • +1
    А для perl`а есть песочница? У меня возникла идея утилиты/программы с большим количеством зависимостей по песочницам раскладывать.

    Вопрос конечно не к автору статьи, а к знающим по теме людям.
    • +1
      Посмотрите на докер, все что угодно можно сделать www.docker.io/
  • –1
    Как понял, версии под windows нету? На работе бы пригодилось (на линукс пересесть не могу, у меня основная технология все-таки .NET ).
    • 0
      Не видел ваш ответ. К сожалению нету, но к вашим услугам все еще множество различных вариантов (от простой установки различных версий PHP в разные папки, до использования виртуальных машин и Vagrant).
  • 0
    Не мог поставить под дебиан 6, команда «phpbrew init» ничего не делала и не говорила, только syslog рассказал:

    Jul 22 16:28:44 debian suhosin[11756]: ALERT - Include filename ('phar://phpbrew.phar/Universal/ClassLoader/SplClassLoader.php') is an URL that is not allowed (attacker 'REMOTE_ADDR not set', file '/usr/bin/phpbrew', line 3)

    Модуль suhosin, если не ошибаюсь, включен по-умолчанию, поэтому если кто столкнулся с такой проблемой, может грешить на suhosin.
    • +1
      Некропостинг. (только увидел комментарий)

      Проблема на поверхности. Suhosin считает phar:// за обычный урл и не дает инклудить файл. Всего-то и надо что добавить phar:// в исключения suhosin

      cweiske.de/tagebuch/suhosin-phar.htm

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.