Настройка требуемой версии PHP для работы с Composer

Раздел: Инструменты разработки -> Настройка Composer

Управление версией PHP для Composer

Как сделать так, чтобы Composer использовал определённую версию PHP?

Наиболее эффективный способ - явно указать путь к бинарному файлу PHP через переменную окружения COMPOSER_PHP_BINARY или передать его непосредственно перед вызовом Composer. Этот метод позволяет временно переключить версию для одной команды, не меняя глобальные настройки системы.

Пример команды:

COMPOSER_PHP_BINARY=/usr/bin/php8.1 composer install

Пояснение: переменная COMPOSER_PHP_BINARY задаёт путь к исполняемому файлу PHP. Composer использует этот интерпретатор для выполнения скриптов (например, скриптов в событии post-install-cmd) и для проверки версии при установке зависимостей. Переменная действует только в рамках текущего сеанса терминала, что удобно для одноразовых задач.

Альтернатива - использовать явный вызов PHP:

/usr/bin/php8.1 /usr/local/bin/composer install

Здесь /usr/bin/php8.1 - путь к PHP, а /usr/local/bin/composer - путь к скрипту Composer. Это надёжнее, так как не зависит от настройки PATH, но требует полного пути.

Типичная ошибка: использование COMPOSER_PHP_BINARY с несуществующим файлом или неверными правами доступа. Composer выдаст сообщение об ошибке наподобие "The COMPOSER_PHP_BINARY environment variable is not set" (если переменная не определена) или "Failed to execute ..." (если файл не найден).

Решение: проверить путь командой which php8.1 или ls -l /usr/bin/php8.1. Для постоянного использования можно добавить переменную в профиль оболочки (например, в ~/.bashrc).

Как сделать php глобальной командой, указывающей на нужную версию?

Системный инструмент update-alternatives (доступен в большинстве дистрибутивов Linux) управляет символическими ссылками, устанавливая, на какую версию PHP будет указывать команда php.

Пример настройки:

sudo update-alternatives --config php

После выполнения отобразится список установленных версий. Выбор номера переключает системную ссылку. Затем Composer будет использовать эту версию по умолчанию.

There are 3 choices for the alternative php (providing /usr/bin/php).

  Selection    Path             Priority   Status
------------------------------------------------------------
* 0            /usr/bin/php8.1   80        auto mode
  1            /usr/bin/php7.4   74        manual mode
  2            /usr/bin/php8.1   80        manual mode
  3            /usr/bin/php8.2   85        manual mode

Press <enter> to keep the current choice[*], or type selection number:

Проблемы: для изменения требуются права суперпользователя (sudo). Если в системе установлена только одна версия, список может быть пустым. Альтернативы не поддерживаются в Windows.

Решение: сначала установите все необходимые версии PHP через репозитории (например, apt install php8.1 php8.2).

Как изолировать версию PHP для одного проекта с помощью Docker?

Docker позволяет запускать Composer в контейнере с фиксированной версией PHP, не затрагивая хост-систему. Официальный образ Composer включает PHP внутри себя.

Пример:

docker run --rm -v "$(pwd):/app" -w /app composer:2.5.8 composer install

Опции: --rm удаляет контейнер после выполнения, -v монтирует текущую директорию в /app, -w устанавливает рабочую директорию. Образ composer:2.5.8 содержит PHP версии, соответствующей образу (например, 8.1 или 8.2 в зависимости от тега).

Ошибка: версия PHP внутри образа может не удовлетворять требованиям composer.json. Например, если проект требует PHP 7.4, а образ содержит 8.0, Composer сообщит о несовместимости.

Решение: использовать более старый тег, например composer:2.2 или создать собственный Dockerfile с нужной версией PHP.

Как автоматически переключать версию PHP для разных проектов с помощью phpenv?

Утилита phpenv (или phpbrew) управляет версиями PHP локально, устанавливая нужную версию для конкретной директории.

Пример настройки:

phpenv install 8.1.28
phpenv local 8.1.28
composer install

Команда phpenv local создаёт файл .php-version в текущей директории. При входе в неё phpenv автоматически переключает PHP. Composer будет вызывать эту версию.

Проблема: phpenv требует предварительной компиляции PHP или установки бинарников. Не все версии доступны, особенно устаревшие.

Решение: убедиться, что phpenv настроен и добавлен в PATH. Команда phpenv versions покажет установленные версии.

Как ограничить минимальную версию PHP в composer.json?

Поле require в composer.json может содержать псевдо-пакет php с указанием диапазона версий.

Пример:

{
    "require": {
        "php": ">=8.0",
        "vendor/package": "^1.0"
    }
}

При выполнении composer install или composer update Composer проверит, соответствует ли текущая версия PHP указанным требованиям. Если нет, будет выдана ошибка.

Ошибка: неправильный синтаксис в версии (например, "8.0" вместо ">=8.0") приводит к тому, что Composer интерпретирует её как точную версию.

Решение: использовать операторы сравнения: >=, <, ~, ^.

Как создать псевдоним для вызова Composer с определённой версией PHP?

В оболочках Bash/Zsh можно определить алиас, который автоматически подставляет нужный PHP.

Пример добавления в ~/.bashrc:

alias composer81='php8.1 /usr/local/bin/composer'
composer81 install

Пояснение: после добавления алиаса команда composer81 будет выполнять php8.1 /usr/local/bin/composer. Алиас действует только в текущем сеансе оболочки, если не помещён в файл конфигурации.

Проблема: алиас не передаётся в дочерние оболочки и не работает в скриптах, где не загружены алиасы.

Решение: для скриптов использовать полный вызов или обёртку в виде функции.

Расширенные примеры работы с версией PHP и Composer

Пример 1. Использование COMPOSER_PHP_BINARY с проверкой версии

В проекте требуется PHP 8.1, но в системе установлены 7.4 и 8.1. Переменная окружения задаётся перед вызовом Composer.

Пример
# Установка переменной и выполнение
COMPOSER_PHP_BINARY=/usr/bin/php8.1 \
  composer require symfony/console
Using version ^6.4 for symfony/console
./composer.json has been updated
Running composer update symfony/console
Loading composer repositories with package information
Updating dependencies
Nothing to modify in lock file
Installing dependencies from lock file (including require-dev)
Package operations: 0 installs, 0 updates, 0 removals
Generating autoload files

Если переменная не задана или указан неверный путь, Composer использует версию PHP по умолчанию, что может вызвать ошибку совместимости:

Пример
composer require symfony/console 2>&1; echo "Exit: $?"
[InvalidArgumentException]
  Could not find package symfony/console with version >=6.4 ...
  The requested PHP version 8.1 is required by the package but you have 7.4.33.

Пример 2. Множественные версии PHP и update-alternatives

Установка трёх версий PHP и переключение между ними.

Пример
# Установка PHP 7.4, 8.1, 8.2
sudo apt update
sudo apt install php7.4 php8.1 php8.2 php7.4-cli php8.1-cli php8.2-cli

# Просмотр списка альтернатив (если уже добавлены)
sudo update-alternatives --list php
# Если пусто, добавить вручную:
sudo update-alternatives --install /usr/bin/php php /usr/bin/php7.4 74 --slave /usr/bin/phar phar /usr/bin/phar7.4
sudo update-alternatives --install /usr/bin/php php /usr/bin/php8.1 81 --slave /usr/bin/phar phar /usr/bin/phar8.1
sudo update-alternatives --install /usr/bin/php php /usr/bin/php8.2 82 --slave /usr/bin/phar phar /usr/bin/phar8.2

# Интерактивное переключение
sudo update-alternatives --config php
There are 3 choices for the alternative php (providing /usr/bin/php).

  Selection    Path             Priority   Status
------------------------------------------------------------
* 0            /usr/bin/php8.2   82        auto mode
  1            /usr/bin/php7.4   74        manual mode
  2            /usr/bin/php8.1   81        manual mode
  3            /usr/bin/php8.2   82        manual mode

Press <enter> to keep the current choice[*], or type selection number: 2

После выбора 2 команда php -v покажет PHP 8.1. Composer также начнёт использовать эту версию.

Пример 3. Docker Compose для Composer с фиксированной версией PHP

Создание файла docker-compose.yml для проекта.

Пример
version: '3.8'
services:
  composer:
    image: composer:2.5.8
    volumes:
      - .:/app
    working_dir: /app
    entrypoint: ["composer"]
    command: ["install"]

Запуск:

Пример
docker-compose run --rm composer

Результат: внутри контейнера выполняется composer install с PHP версии, встроенной в образ (например, 8.1). Если нужно явно указать PHP более старой версии, используется образ с тегом composer:2.2 (содержит PHP 7.4).

Пример 4. phpenv: установка PHP и привязка к проекту

Предварительно phpenv установлен (инструкция на github.com/phpenv/phpenv).

Пример
# Установка PHP 7.4.33
phpenv install 7.4.33
# Список установленных
phpenv versions
# Переход в директорию проекта
cd /home/user/project
# Установка локальной версии
phpenv local 7.4.33
# Проверка
php -v
# Запуск Composer
composer install
PHP 7.4.33 (cli) (built: Nov  9 2023 12:00:00) ( NTS )
...
Loading composer repositories with package information
Installing dependencies (including require-dev) from lock file ...

Файл .php-version в корне проекта позволяет автоматически переключать версию при каждом входе в директорию (если настроен хук в оболочке).

Пример 5. composer.json с точным указанием версии PHP и проверка

Требование: проект работает только на PHP 8.0.x (не 8.1).

Пример
{
    "require": {
        "php": "8.0.*",
        "monolog/monolog": "^2.0"
    }
}

Попытка установить зависимости на системе с PHP 8.1:

Пример
composer install
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - Root composer.json requires PHP 8.0.* but your PHP version (8.1.12) does not satisfy that requirement.

Если же PHP версии 8.0.x установлена и используется, установка пройдёт успешно.

Пример 6. Алиас в .bashrc для нескольких версий Composer

Пример
# В ~/.bashrc
alias composer7='php7.4 /usr/local/bin/composer'
alias composer8='php8.1 /usr/local/bin/composer'
alias composer82='php8.2 /usr/local/bin/composer'

# Перезагрузка
source ~/.bashrc

# Использование
composer8 require laravel/framework
Using version ^10.0 for laravel/framework
...

Для автоматического определения версии по composer.json можно написать функцию:

Пример
function composer() {
    local phpVer=$(php -r 'echo PHP_MAJOR_VERSION.".".PHP_MINOR_VERSION;');
    case $phpVer in
        7.4) command php7.4 "$(which composer)" "$@";;
        8.1) command php8.1 "$(which composer)" "$@";;
        8.2) command php8.2 "$(which composer)" "$@";;
        *) command php "$(which composer)" "$@";;
    esac
}

Версия PHP для Composer - comments

En
Composer php version (php)