Программисты делятся на два типа: консерваторы, для которых переход на новую версию равносилен перелёту на другую планету (если читаешь это из Windows XP — поздравляю, это ты); и Викторы Цои, чьи сердца и глаза требуют перемен, и обновляют всё и вся при первой возможности. Если ты второго типа, и у тебя уже стоит последняя версия PHP на последней версии Ubuntu, но покоя не даёт то, что расширение Intl использует устаревшую версию библиотеки ICU, или тебе просто понравились картинки из «Аватара» — добро пожаловать под кат! (Картинок больше не будет.)

Аватар


Ну и зачем это?


Библиотека ICU с каждым релизом добавляет поддержку стандартов транслитерации для различных языков, добавляет новые функции и возможности, фиксит баги. Пока неизвестно, по какой причине PHP нерегулярно обновляет ICU в расширении Intl. Поэтому приходится всё брать в свои руки.

Поиск решения


Быстрый поиск по гуглу не дал внятных решений. Детальный тоже. В общем и целом пэхэпэшным программистам по барабану, какую версию ICU использует Intl. Но только не нашим! Отчаявшись искать в англоязычном сегменте интернета, совершенно случайно набрёл на запись русского блогера Сергея Стоянова, где он объясняет процесс обновления ICU в PHP 5 для Ubuntu 14.04. В PHP 7 процесс сильно отличается, но общая последовательность действий остаётся такой же: удаляем Intl; собираем новую версию ICU; устанавливаем Intl, ткнув его носом, где искать ICU; включаем Intl в PHP; открываем шампанское. Также сильно помогли комментарии к статье (особенно комментарий Антона Минина и его shell скрипт).

Версии ICU


Проверить последнюю версию ICU можно на их официальном сайте. На данный момент (февраль 2018) последний релиз — 60.2.

Чтобы проверить, какую версию ICU использует php7.0-intl, напиши в терминале
php -i
и прокрути до списка установленных модулей. Найди там раздел, озаглавленный «intl». У меня там было:
Internationalization support => enabled
version => 1.1.0
ICU version => 55.1
ICU Data version => 55.1
Мягко говоря, не айс — версия 55.1 была выпущена в первой половине 2015-го, и с тех пор успела обновиться ещё 5 раз. Нужно же что-то делать!

Решение


  1. Проверяем полное название расширения Intl (для PHP 7 обычно это php7.0-intl):
    sudo dpkg --get-selections | grep -v deinstall | grep php
  2. Удаляем расширение Intl:
    sudo apt-get remove php7.0-intl
  3. Устанавливаем phpize:
    sudo apt install php7.0-dev
  4. Устанавливаем git (если его нет):
    sudo apt install git
  5. Устанавливаем icu-install.sh (в оригинальном скрипте было 2 ошибки, поэтому здесь использую мой форк):
    git -C /tmp clone https://gist.github.com/siffash/76676186de0ffc6eb6cbf89abc7a5e2f icu-install
  6. Разрешаем скрипту запускаться:
    sudo chmod +x /tmp/icu-install/icu-install.sh
  7. Проверяем доступные версии ICU:
    sudo /tmp/icu-install/icu-install.sh versions
  8. Выбираем последнюю (60.2) и запускаем установку:
    sudo /tmp/icu-install/icu-install.sh install 60.2
  9. Подключаем intl.so в php.ini:
    sudo touch /etc/php/7.0/apache2/conf.d/20-intl.ini && sudo bash -c 'echo "extension=intl.so" > /etc/php/7.0/apache2/conf.d/20-intl.ini'
    
  10. Перезапускаем Apache:
    /etc/init.d/apache2 restart
  11. Удаляем phpize:
    sudo apt-get purge --auto-remove php7.0-dev
  12. Удаляем shell скрипт:
    rm -rf /tmp/icu-install

Теперь проверяем версию ICU в
php -i
и прыгаем до потолка:
Internationalization support => enabled
version => 1.1.0
ICU version => 60.2
ICU Data version => 60.2
P.S. Если у тебя есть англоязычные друзья и ты спешишь поделиться с ними радостной вестью, вот тебе версия на англицком из моего англоязычного блога.

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


  1. sumanai
    09.02.2018 17:15

    если читаешь это из Windows XP — поздравляю, это ты

    Впервые ко мне обращаются из топика на Хабре.


    1. siffash Автор
      09.02.2018 17:18

      Боюсь спрашивать, каким браузером пользуетесь.


      1. sumanai
        09.02.2018 17:21

        Последний Basilisk на основе 55 FireFox, в 64 битной редакции. Всё равно более новые редакции этого браузера не поддерживают и пятой части нужных мне дополнений, так что я его поставлю даже на десятку.


  1. YaRobot
    09.02.2018 20:37

    у тебя уже стоит последняя версия PHP на последней версии Ubuntu...

    У меня последняя версия MacOs, но нас вы как то обошли стороной =(


    1. siffash Автор
      09.02.2018 20:43

      Каюсь, у меня самого PHP и на Windows стоит, но на текущий момент нужен был апгрейд в PHP именно под Линукс.


  1. OnYourLips
    10.02.2018 10:36
    +1

    Хочу обратить внимание на php.net/supported-versions.php

    Рекомендую держать версию PHP в зеленой зоне.
    Если бы вы это делали и периодически обновляли PHP на минорные релизы и постоянно на патч-релизы, то не столкнулись бы с проблемой.

    Однако это подходит лишь для живых проектов. Мертвые (с завершенной стадией поддержки) просто так не выйдет перевести на новую версию.


    1. siffash Автор
      10.02.2018 17:53

      При апргрейде PHP на 7.2 (которого, кстати, ещё нет в официальном репозитории Убунту) крашнулся весь проект, который, по всей видимости, был написан под 7.0. Мне же для добавления определённых фич (с использованием новых возможностей последнего релиза ICU) необходим был точечный апгрейд именно Intl.


      1. OnYourLips
        10.02.2018 18:54

        Надо обдуманно обновлять: переключить версию на локальной копии, запустить тесты, а потом уже думать о продакшене. Причем и продакшен лучше переключать частями: например 10% трафика пустить на новую версию и смотреть на мониторинг.


        1. siffash Автор
          10.02.2018 18:57

          Слава Богу, это был не продакшен, так что краш был не фатальным.