Я хотел написать небольшую статью про то как работает композер. Как раз про "Строим циклическое дерево, потом переводим дерево в линейный список, ...". После того как я перечитал, что получилось то понял, что тема будет интересна только тем, кто ее уже знает. Поэтому я решил, немного изменить тему и рассказать побольше, про работу композера не вдаваясь в его код.

Сomposer имеет значительно больше опций и параметров, чем просто "install, update". Полный список всех параметров можно посмотреть в документации композера. Я разберу несколько пунктов, которые, как мне кажется, очень полезны, но крайне редко используемы.

Одним из таких пунктов является пункт "replace". В нем можно указать, какие пакеты заменяет текущий пакет. Это может быть полезно, когда вы делаете альтернативу какому-то другому пакету и при этом вы даете другое имя для своего пакета. Вы укажите заменяемый пакет в блоке "replace" и composer поймет, что вместо этого пакета во всех зависимостях нужно использовать ваш пакет.

Следующий интересный параметр - это блок "suggest". В этом блоке указываются дополнительные пакеты, установка которых может дать какой-то плюс к работе системы. При вызове команды install или update, composer напишет предложение об установке этих пакетов. На самом деле, не так давно я читал обсуждение о том стоит ли вообще использовать этот блок и есть ли от этого блока польза. На мой взгляд, использование системы с деградацией хотя и создает дополнительную сложность в разработке, однако способно сделать систему, которая будет подходить под значительно более широкий круг задач.

Нельзя не упомянуть про блок "extra". В этом блоке записываются любые произвольные данные, которые нужно передать в composer для обновления:

    "extra": {
        "symfony-app-dir": "app",
        "symfony-web-dir": "web"
    }

И последний этой группы - это "config". Как можно понять из названия - это блок в котором содержатся настройки. При этом настройки в этом блоке будут применены только файл composer.json относится к самому проекту, а не к одному из пакетов. Настройки содержат много полезных параметров. Например, параметр "process-timeout" - определяет сколько времени дается на скачиваение одного пакета. По умолчанию, параметр равен 300 секундам, но если у вас в проекте используется большой пакет то значение стоит увеличить. Кроме того, там же находится параметр "vendor", который указывает, где находится vendor директория.

При работе composer почти всегда имеет возможность выбрать один из нескольких плагинов, или одну версию из нескольких. Этот выбор происходит автоматически, однако, если необходимо, то на выбор можно повлиять. Посмотрим, как composer принимает решение, какой пакет выбрать. Для этого у него есть несколько правил:

  1. Если у вас стоит зависимость от пакета "A" и он есть в 3 вариантах (Av1, Av2, Av3), то будет установлена самая последняя версия "Av3". Подразумевается, что самая последняя версия будет самой лучшей и самой стабильной.
  2. Для спорных ситуаций между разными пакетами (например, если есть два пакета и один из них заменяет другой), композер принимает решения на основе приоритета одного пакета перед другим.

Приоритеты сравниваются по следующим правилам:

  • Высший приоритет у алиасов (то есть у тех пакетов, которые вы сделали, как замену оригинальным или в которых в качестве версии используется алиас)
  • Чуть меньше приоритет, у пакета, который сам входит в require лист
  • Если после первых двух сравнений приоритетный пакет не определен, то приоритетным считается пакет, который записан первым

Это небольшой обзор того интересного, что есть в composer. Надеюсь, что эта статья поможет немного упростить работу и даст хороший стимул больше читать документацию.