Гид по технологиям

Патчинг PHP-пакетов, установленных через Composer

• 6 min read • Development • Обновлено 28 Nov 2025
Патчинг PHP-пакетов через Composer
Патчинг PHP-пакетов через Composer

Логотип PHP

Быстрые ссылки

  • Когда стоит патчить пакет

  • Создание патча для Composer

  • Создание файла патча

  • Автоматическое применение патчей

  • Удаление патчей

Когда стоит патчить пакет

Перед тем как патчить зависимость внутри проекта, оцените альтернативы. Патч внутри проекта должен быть небольшим, целевым и временным. Патчи уместны, если они:

  • Исправляют критическую ошибку, блокирующую релиз или работу приложения.
  • Влияют на несколько строк кода и не вносят архитектурных изменений.
  • Не предназначены для постоянного расширения функциональности библиотеки.

Когда патч не подходит:

  • Нужно добавить крупную функциональность — лучше форкнуть пакет или предложить PR в upstream.
  • Требуется изменить публичный API библиотеки — тогда лучше создать обёртку (adapter/wrapper) в своём коде.
  • Патч предполагает внесение изменений, затрагивающих множество файлов — это повышает риск конфликтов при обновлениях.

Короткая формула принятия решения: если исправление срочное и локальное — патч уместен; если это долгосрочное изменение дизайна — выбирайте PR/форк/обёртку.

Создание патча для Composer

Composer не поддерживает патчи «из коробки», поэтому рекомендуется использовать пакет-обёртку, который упрощает рабочий процесс. Популярный выбор — symplify/vendor-patches, который предоставляет удобные команды поверх cweagans/composer-patches.

Установите пакет разработки:

composer require --dev symplify/vendor-patches

Убедитесь, что нужный пакет уже установлен в проекте:

composer require example/broken-package

Откройте файл, который нужно исправить, в каталоге vendor. В примере мы редактируем:

vendor/example/broken-package/src/Broken.php

Исходный (проблемный) файл в примере выглядит так:

Здесь автор намеревался принимать и строки, и числа (union-тип string|int в PHP 8), но реализация фактически обрабатывает только строки. Допустим, автор уже в курсе проблемы, но новый релиз ещё не выпущен — можно временно патчить.

Процесс безопасного создания патча:

  1. Скопируйте оригинал в файл с суффиксом .old (без изменений) — он будет использоваться для расчёта diff:
cp vendor/example/broken-project/src/Broken.php vendor/example/broken-project/src/Broken.php.old
  1. Не редактируйте файл .old.
  2. Отредактируйте оригинальный файл vendor/example/broken-project/src/Broken.php так, чтобы он корректно работал в вашем коде. Патчи применяются в момент установки зависимостей, поэтому изменения сразу влияют на выполнение вашего приложения.

Исправленный пример:

Проверьте поведение вашего приложения локально перед генерацией патча.

Создание файла патча

После того как вы внесли изменения, используйте vendor-patches для генерации файла патча. Утилита сканирует каталог vendor и сравнивает текущие файлы с их .old-версиями.

Запустите генерацию:

vendor/bin/vendor-patches generate

Команда создаст diff и сохранит его в каталоге patches в корне проекта. Каждый изменённый файл даёт отдельный .patch.

Советы по патчу:

  • Держите патч минимальным: только те изменения, которые необходимы для исправления.
  • Добавляйте заголовок и описание в тело .patch, чтобы коллеги понимали, зачем он нужен.
  • Версионируйте патчи в системе контроля версий вместе с коммитом, который изменил файл .old и сгенерировал патч.

Автоматическое применение патчей

После генерации патчей ваш composer.json должен содержать секцию extra.patches. Пример структуры в composer.json:

{
  "extra": {
    "patches": {
      "example/broken-package": [
        "patches/example-broken-package-src-broken-php.patch"
      ]
    }
  }
}

Обёртка регистрирует установочный скрипт, который при установке или обновлении зависимостей проверяет наличие патчей и пытается их применить. При выполнении composer install вы увидите строки в выводе, подтверждающие применение патча.

Если патч пропускается, запустите с подробным выводом для диагностики:

composer install --verbose

Частые причины пропуска патчей:

  • upstream уже исправил проблему в новой версии пакета — патч становится неактуальным.
  • Структура файлов изменилась, и патч не может быть применён чисто.
  • Патч конфликтует с другим патчем или локальными изменениями.

Удаление патчей

Чтобы временно отключить патч — удалите соответствующую строку в composer.json. Чтобы полностью удалить патч из проекта:

  1. Удалите запись в composer.json в секции extra.patches.
  2. Удалите .patch-файл из каталога patches.
  3. При необходимости удалите пакет из vendor и выполните composer install для восстановления чистого состояния.

Если вы хотите откатить локально применённый патч, проще всего удалить или отключить запись и переустановить зависимости.

Когда патч не подойдёт (примеры и контрпримеры)

Подходит:

  • Небольшая правка байткода или логики, мешающая запуску приложения.
  • Исправление уязвимости безопасности до выхода исправления в upstream.

Не подходит:

  • Требуется добавить новую подсистему или изменить публичный API — тогда лучше форк или PR.
  • Патч перекрывает тесты пакета и требует изменений множества модулей — высок риск регрессий.

Важно: храните в патче ссылку на issue/PR в upstream, чтобы позже проверить, можно ли удалить патч.

Альтернативные подходы

  1. Создать PR (pull request) в репозитории пакета — лучший вариант для долгосрочного решения.
  2. Форкнуть пакет и использовать собственную версию через репозиторий или VCS-ссылку в composer.json.
  3. Обёртка (adapter/wrapper): написать свой класс, который инкапсулирует вызовы проблемного API и предоставляет нужный интерфейс.
  4. Временно заменить пакет другим, если это приемлемо по объёму работ.

Каждый подход имеет свои плюсы и минусы по затратам на поддержку, совместимости и скорости внедрения.

Мини-методика: как безопасно применять патч в команде

  1. Оцените изменение и подтвердите, что оно минимально и безопасно.
  2. Создайте .old-файлы и сгенерируйте патч локально.
  3. Добавьте патч в каталог patches и зафиксируйте в VCS с подробным сообщением и ссылкой на issue.
  4. Откройте MR/PR в вашем репозитории, чтобы коллеги могли проверить патч.
  5. После проверки и слияния документируйте патч и назначьте владельца для мониторинга upstream.
  6. Как только upstream решит проблему — удалите патч.

Чек-лист по ролям

Разработчик:

  • Подготовил .old и сгенерировал патч.
  • Написал краткое описание в патче и ссылку на issue.
  • Проверил, что тесты проходят с патчем.

Ревьюер/ведущий команды:

  • Оценил риск изменения и согласовал временность решения.
  • Проверил отсутствие побочных эффектов в смежных областях.

Релиз-инженер / DevOps:

  • Убедился, что CI применяет патчи и артефакты собираются.
  • Контролирует вывод composer install и логи применения патчей.

Модель принятия решения — блок-схема

flowchart TD
  A[Возникла ошибка в зависимости] --> B{Можно ли обойти проблему без изменений в пакете?}
  B -- Да --> C[Применить обход 'конфигурация/обёртка']
  B -- Нет --> D{Изменение минимально и временно?}
  D -- Да --> E[Сделать патч в проекте]
  D -- Нет --> F{Возможен PR или форк?}
  F -- PR --> G[Открыть PR в upstream и ждать релиз]
  F -- Форк --> H[Форкнуть пакет и использовать свой VCS-репозиторий]
  E --> I[Сгенерировать .patch и добавить в composer.json]
  I --> J[Контролировать и удалять после релиза]

Критерии приёмки

  • Патч минимален и документирован.
  • Тесты на критические сценарии проходят с патчем.
  • В PR указана ссылка на issue в upstream и план удаления патча после релиза.
  • Есть ответственный за мониторинг состояния upstream.

Глоссарий (одной строкой)

  • Патч — diff-файл, который изменяет файлы пакета при установке.
  • upstream — исходный репозиторий пакета, где поддерживается проект.
  • .old-файл — копия оригинала, используемая для генерации diff.

Примечания и рекомендации

  • Храните патчи в VCS и давайте им понятные имена, отражающие пакет и файл.
  • Регулярно проверяйте upstream на исправления, чтобы вовремя удалить патчи.
  • По возможности создавайте PR в upstream: это снижает технический долг и нагрузку на вашу команду.

Важное: патчи — мощный инструмент экстренной починки, но они несут долгосрочные издержки. Используйте их осознанно и документируйте каждое изменение.

Итог

Патчинг пакетов Composer — рабочая стратегия для быстрого исправления проблем, когда upstream ещё не выпустил релиз. Использование symplify/vendor-patches упрощает генерацию и автоматическое применение патчей. Всегда документируйте патчи, поддерживайте их в VCS и планируйте удаление, как только upstream решит проблему.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро