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

    Лирическое №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
    Поделиться публикацией
    Похожие публикации
    AdBlock похитил этот баннер, но баннеры не зубы — отрастут

    Подробнее
    Реклама
    Комментарии 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

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