Предлагаю читателям «Хабрахабра» перевод статьи «Mastering Composer – Tips and Tricks» за авторством Bruno Skvorc.

Composer logo

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

Глобальная установка (Global)


Несмотря на то, что данная опция доступно описана в документации, Composer может (а в большинстве случаев должен) быть установлен глобально. Глобальная установка означает, что вместо:

php composer.phar somecommand

Вы можете в любом проекте просто ввести:

composer somecommand

Это позволяет очень просто создавать новые проекты (например, с помощью команды create-project) в любом месте вашей файловой системы.

Для установки Composer глобально, следуйте этим инструкциям.

Правильная установка зависимостей


При чтении вводных инструкций или README файлов многие напишут вам что-то вроде:
Just add the following to your composer.json file:
{
    "require": {
        "myproject": "someversion"
    }
}


Но данный подход имеет несколько недостатков. Во-первых, простой копипаст может привести к возникновению ошибок. Во-вторых, для новичка может быть не очевидно, где разместить данный код, если у него и так уже имеется обширный файл composer.json, и это также привести к ошибке. Наконец, некоторые люди будут иметь дело с Composer впервые, а возможно и впервые столкнутся с командной строкой. Поэтому хорошей практикой будет освещение всевозможных случаев, в которых новички могут чувствовать себя неуверенно (есть ли у них графический редактор или они будут использовать командную строку? Если второе, установлен ли в ней текстовый редактор, и если да, то какой? Объясняете ли вы саму процедуру редактирования файла? А что если файла composer.json ещё не существует в проекте? Описываете ли также принцип создания нового файла?).

Наилучший способ добавить новую зависимость в файл composer.json — это воспользоваться командой require:

composer require somepackage/somepackage:someversion

Это добавит все необходимое в файл зависимостей, минуя ручное вмешательство.

Если вам нужно добавить пакеты в раздел require-dev, добавьте в команду опцию --dev:

composer require phpunit/phpunit --dev

Также, команда require поддерживает добавление нескольких пакетов одновременно, для этого просто разделите их пробелом.

Файлы блокировок


Файл composer.lock сохраняет текущий список установленных зависимостей и их версии. Таким образом, на момент, когда версии зависимостей уже будут обновлены, другие люди, которые будут клонировать ваш проект, получат те же самые версии. Это позволяет убедиться в том, что каждый, кто получает ваш проект, имеет “пакетное окружение”, идентичное тому, которое вы использовали при разработке, и помогает избежать ошибок, которые могли бы возникнуть из-за обновления версий.

Файл composer.lock почти всегда должен быть добавлен в систему контроля версий (не всегда).

Также, файл composer.lock содержит хэш файла composer.json, так что, если вы даже просто обновляете данные об авторе проекта, вы получите предупреждение о том, что файл блокировки не соответствует .json файлу. В таком случае, поможет команда composer update --lock, которая обновит только сам файл блокировки, не касаясь ничего другого.

Версионирование


При указании допустимых версий пакетов можно использовать точное соответствие (1.2.3), диапазоны с операторами сравнения (<1.2.3), комбинации этих операторов (>1.2.3 <1.3), “последняя доступная” (1.2.*), символ тильды (~1.2.3) и знак вставки (^1.2.3).

Последние два указания достойны отдельного объяснения:
  • указание тильды (~1.2.3) будет включать в себя все версии до 1.3 (не включительно), так как в семантическом версионировании это является моментом внедрения новых функциональных возможностей. В данном случае будет получена последняя из стабильных минорных версий. Как гласит документация, при данном указании изменяться может только последняя цифра версии.
  • указание знака вставки (^1.2.3) буквально означает “опасаться только критических изменений” и будет включать в себя версии вплоть до 2.0. Применительно к semver, изменение мажорной версии является моментом внесения в проект критических изменений, так что версии 1.3, 1.4 и 1.9 подходят, в то время как 2.0 — уже нет.

Кроме случая, когда вы знаете, что вам нужна конкретная версия пакета, я рекомендую всегда использовать формат ~1.2.3 — это самый безопасный выбор.

Локальная и глобальная конфигурация


Значения параметров по-умолчанию не высечены на камне. Подробное описание возможных параметров конфигураций (config) см. по ссылке.

Например, указав:
{
    "config": {
        "optimize-autoloader": true
    }
}

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

Ещё одним полезным параметром может быть cache-files-maxsize. В больших проектах (как eZ Publish или Symfony) кэш может заполниться довольно быстро. Увеличение размера кэша позволить Composer работать быстро дольше.

Обратите внимание, что параметры конфигурации могут быть установлены глобально, и в таком случае будут действовать на все проекты (см. config). Например, чтобы глобально установить параметр размера кэша, нужно либо отредактировать файл ~/.composer/config.json, либо выполнить:

composer config --global cache-files-maxsize "2048MiB"


Профилирование и подробный вывод (verbose)


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

[174.6MB/54.70s] Memory usage: 174.58MB (peak: 513.47MB), time: 54.7s

Но также в начало каждой строки вывода будет добавлено время выполнения команды и использованный размер памяти:

[175.9MB/54.64s] Installing assets for Sensio\Bundle\DistributionBundle into web/bundles/sensiodistribution

Я использую данную опцию для определения “медленных” пакетов и для наблюдения за улучшением или ухудшением производительности на разных версиях PHP.

Подобно предыдущему, параметр --verbose заставит Composer выводить больше информации о каждой выполняемой операции, давая вам понять, что именно происходит в данный момент. Некоторые люди даже устанавливают composer --verbose --profile псевдонимом команды composer по-умолчанию.

Пользовательские источники


Если ваш проект ещё не на Packagist, иногда вам нужно просто установить пакет с GitHub (например, если пакет ещё находится в разработке). Для этого см. наше руководство.

Когда у вас есть своя версия популярного пакета, от которого зависит ваш проект, вы можете использовать пользовательские источники в сочетании с контекстными псевдонимами (inline aliasing), чтобы подставить собственную ветку для публичного пакета, как здесь описал Matthieu Napoli.

Ускорение Composer


Используя отличный метод, описанный Mark Van Eijk, вы можете ускорить выполнение Composer, вызывая его через HHVM.

Ещё один способ — с помощью параметра --prefer-dist, при установке которого Composer будет скачивать стабильные, запакованные версии проекта, вместо клонирования из системы контроля версий (что значительно медленнее). Этот параметр используется по-умолчанию, так что вам не нужно включать его на стабильных проектах. Если вам нужно загрузить проект из исходников, используйте параметр --prefer-source. Подробнее об этом можно узнать в разделе install здесь.

Уменьшение размера проекта Composer


Если вы разработчик «Composer-friendly» проектов, данная часть вас также заинтересует. По этому посту в Reddit, вы можете с помощью файла .gitattributes игнорировать некоторые файлы и папки во время упаковки пакета для режима --prefer-dist.
/docs               export-ignore
/tests              export-ignore
/.gitattributes     export-ignore
/.gitignore         export-ignore
/.travis.yml        export-ignore
/phpunit.xml        export-ignore

Как это работает? Когда вы загружаете проект на GitHub, он автоматически делает доступным ссылку “Download zip”, с помощью которой вы можете скачать архив вашего проекта. Более того, Packagist использует эти автоматически сгенерированные архивы для скачивания зависимостей с опцией --prefer-dist, которые он затем локально разархивирует (намного быстрее клонирования исходных файлов проекта). Если вы при этом добавите в .gitattributes тесты, документацию и прочие файлы, не имеющие отношения к логике работы проекта, указанные архивы не будут их содержать, став гораздо легче.

При этом людям, которые захотят отладить вашу библиотеку или запустить тесты, нужно будет указать параметр --prefer-source.

PhpLeague приняла этот подход и включила его в свой «скелет пакета» (Package skeleton), так что любой основанный на нем проект автоматически будет “dist friendly”.

Show


Если вы вдруг забыли, какую версию PHP или его расширения используете, или вам нужен список всех установленных проектов (с описанием каждого) с их версиями, вы можете использовать команду show с параметрами --platform (-p) и --installed (-i):

composer show --installed
$ composer show --installed
 
behat/behat                            v3.0.15            Scenario-oriented BDD framework for PHP 5.3
behat/gherkin                          v4.3.0             Gherkin DSL parser for PHP 5.3
behat/mink                             v1.5.0             Web acceptance testing framework for PHP 5.3
behat/mink-browserkit-driver           v1.1.0             Symfony2 BrowserKit driver for Mink framework
behat/mink-extension                   v2.0.1             Mink extension for Behat
behat/mink-goutte-driver               v1.0.9             Goutte driver for Mink framework
behat/mink-sahi-driver                 v1.1.0             Sahi.JS driver for Mink framework
behat/mink-selenium2-driver            v1.1.1             Selenium2 (WebDriver) driver for Mink framework
behat/sahi-client                      dev-master ce7bfa7 Sahi.js client for PHP 5.3
behat/symfony2-extension               v2.0.0             Symfony2 framework extension for Behat
behat/transliterator                   v1.0.1             String transliterator
components/bootstrap                   3.3.2              The most popular front-end framework for developing responsive, mobile first projects on the web.
components/jquery                      2.1.3              jQuery JavaScript Library
doctrine/annotations                   v1.2.4             Docblock Annotations Parser
doctrine/cache                         v1.4.1             Caching library offering an object-oriented API for many cache backends
doctrine/collections                   v1.3.0             Collections Abstraction library
doctrine/common                        v2.5.0             Common Library for Doctrine projects
doctrine/dbal                          v2.5.1             Database Abstraction Layer
doctrine/doctrine-bundle               v1.4.0             Symfony DoctrineBundle
doctrine/doctrine-cache-bundle         v1.0.1             Symfony2 Bundle for Doctrine Cache
doctrine/inflector                     v1.0.1             Common String Manipulations with regard to casing and singular/plural rules.
doctrine/instantiator                  1.0.4              A small, lightweight utility to instantiate objects in PHP without invoking their constructors
doctrine/lexer                         v1.0.1             Base library for a lexer that can be used in Top-Down, Recursive Descent Parsers.
egulias/listeners-debug-command-bundle 1.9.1              Symfony 2 console command to debug listeners
ezsystems/behatbundle                  dev-master bd95e1b Behat bundle for help testing eZ Bundles and projects
ezsystems/comments-bundle              dev-master 8f95bc7 Commenting system for eZ Publish
ezsystems/demobundle                   dev-master c13fb0b Demo bundle for eZ Publish Platform
ezsystems/demobundle-data              v0.1.0             Data for ezsystems/demobundle
ezsystems/ezpublish-kernel             dev-master 3d6e48d eZ Publish API and kernel. This is the heart of eZ Publish 5.
ezsystems/platform-ui-assets-bundle    v0.5.0             External assets dependencies for PlatformUIBundle
ezsystems/platform-ui-bundle           dev-master 4d0442d eZ Platform UI Bundle
ezsystems/privacy-cookie-bundle        v0.1               Privacy cookie banner integration bundle into eZ Publish/eZ Platform
fabpot/goutte                          v1.0.7             A simple PHP Web Scraper
friendsofsymfony/http-cache            1.3.1              Tools to manage cache invalidation
friendsofsymfony/http-cache-bundle     1.2.1              Set path based HTTP cache headers and send invalidation requests to your HTTP cache
guzzle/guzzle                          v3.9.3             PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle
hautelook/templated-uri-bundle         2.0.0              Symfony2 Bundle that provides a RFC-6570 compatible router and URL Generator.
hautelook/templated-uri-router         2.0.1              Symfony2 RFC-6570 compatible router and URL Generator
imagine/imagine                        0.6.2              Image processing for PHP 5.3
incenteev/composer-parameter-handler   v2.1.0             Composer script handling your ignored parameter file
instaclick/php-webdriver               1.0.17             PHP WebDriver for Selenium 2
jdorn/sql-formatter                    v1.2.17            a PHP SQL highlighting library
knplabs/knp-menu                       v1.1.2             An object oriented menu library
knplabs/knp-menu-bundle                v1.1.2             This bundle provides an integration of the KnpMenu library
kriswallsmith/assetic                  v1.2.1             Asset Management for PHP
kriswallsmith/buzz                     v0.13              Lightweight HTTP client
league/flysystem                       0.5.12             Many filesystems, one API.
liip/imagine-bundle                    1.2.6              This Bundle assists in imagine manipulation using the imagine library
monolog/monolog                        1.13.1             Sends your logs to files, sockets, inboxes, databases and various web services
nelmio/cors-bundle                     1.3.3              Adds CORS (Cross-Origin Resource Sharing) headers support in your Symfony2 application
ocramius/proxy-manager                 0.5.2              A library providing utilities to generate, instantiate and generally operate with Object Proxies
oneup/flysystem-bundle                 v0.4.2             Integrates Flysystem filesystem abstraction library to your Symfony2 project.
pagerfanta/pagerfanta                  v1.0.3             Pagination for PHP 5.3
phpdocumentor/reflection-docblock      2.0.4              
phpspec/prophecy                       v1.4.1             Highly opinionated mocking framework for PHP 5.3+
phpunit/php-code-coverage              2.0.16             Library that provides collection, processing, and rendering functionality for PHP code coverage information.
phpunit/php-file-iterator              1.4.0              FilterIterator implementation that filters files based on a list of suffixes.
phpunit/php-text-template              1.2.0              Simple template engine.
phpunit/php-timer                      1.0.5              Utility class for timing
phpunit/php-token-stream               1.4.1              Wrapper around PHP's tokenizer extension.
phpunit/phpunit                        4.6.4              The PHP Unit Testing framework.
phpunit/phpunit-mock-objects           2.3.1              Mock Object library for PHPUnit
psr/log                                1.0.0              Common interface for logging libraries
qafoo/rmf                              1.0.0              Very simple VC framework which makes it easy to build HTTP applications / REST webservices
sebastian/comparator                   1.1.1              Provides the functionality to compare PHP values for equality
sebastian/diff                         1.3.0              Diff implementation
sebastian/environment                  1.2.2              Provides functionality to handle HHVM/PHP environments
sebastian/exporter                     1.2.0              Provides the functionality to export PHP variables for visualization
sebastian/global-state                 1.0.0              Snapshotting of global state
sebastian/recursion-context            1.0.0              Provides functionality to recursively process PHP variables
sebastian/version                      1.0.5              Library that helps with managing the version number of Git-hosted PHP projects
sensio/distribution-bundle             v3.0.21            Base bundle for Symfony Distributions
sensio/framework-extra-bundle          v3.0.7             This bundle provides a way to configure your controllers with annotations
sensio/generator-bundle                v2.5.3             This bundle generates code for you
sensiolabs/security-checker            v2.0.2             A security checker for your composer.lock
swiftmailer/swiftmailer                v5.4.0             Swiftmailer, free feature-rich PHP mailer
symfony-cmf/routing                    1.3.0              Extends the Symfony2 routing component for dynamic routes and chaining several routers
symfony/assetic-bundle                 v2.6.1             Integrates Assetic into Symfony2
symfony/monolog-bundle                 v2.7.1             Symfony MonologBundle
symfony/swiftmailer-bundle             v2.3.8             Symfony SwiftmailerBundle
symfony/symfony                        v2.6.6             The Symfony PHP framework
tedivm/stash                           v0.12.3            The place to keep your cache.
tedivm/stash-bundle                    v0.4.2             Incorporates the Stash caching library into Symfony.
twig/extensions                        v1.2.0             Common additional features for Twig that do not directly belong in core
twig/twig                              v1.18.1            Twig, the flexible, fast, and secure template language for PHP
white-october/pagerfanta-bundle        v1.0.2             Bundle to use Pagerfanta with Symfony2
whiteoctober/breadcrumbs-bundle        1.0.2              A small breadcrumbs bundle for Symfony2
zendframework/zend-code                2.2.10             provides facilities to generate arbitrary code using an object oriented interface
zendframework/zend-eventmanager        2.2.10             
zendframework/zend-stdlib              2.2.10             
zetacomponents/base                    1.9                The Base package provides the basic infrastructure that all packages rely on. Therefore every component relies on this package.
zetacomponents/feed                    1.4                This component handles parsing and creating RSS1, RSS2 and ATOM feeds, with support for different feed modules (dc, content, creativeCommons, geo, iTunes).
zetacomponents/mail                    1.8.1              The component allows you construct and/or parse Mail messages conforming to  the mail standard. It has support for attachments, multipart messages and HTML  mail. It also interfaces with SMTP to send mail or IMAP, P...
zetacomponents/system-information      1.1                Provides access to common system variables, such as CPU type and speed, and the available amount of memory.


Репетиции (Dry Runs)


Чтобы просто посмотреть, пройдет ли установка новых зависимостей успешно, вы можете использовать параметр --dry-run для команд install и update. Composer в данном случае выведет все потенциальные проблемы без непосредственного выполнения самой команды. Никаких реальных изменений в проекте не произойдет. Этот прием отлично подходит для тестирования сложных зависимостей и настройки изменений перед реальным их внесением.

composer update --dry-run --profile --verbose

Создание проекта


Последнее, но не менее важное, что мы должны упомянуть — это команда create-project.

Команда создания проекта принимает в качестве аргумента имя пакета, который она затем клонирует и выполняет composer install внутри него. Это отлично подходит для инициализации проектов — не нужно больше искать Url нужного пакета на GitHub, клонировать его, самому переходить в папку и выполнять команду install.

Крупные проекты, такие как Symfony и Laravel, уже используют данный подход для инициализации своих «skeleton» приложений, и многие другие также присоединяются.

Например, в Laravel это используется следующим образом:

composer create-project laravel/laravel --prefer-dist --profile --verbose

В команду create-project можно передать еще два параметра: путь, в который нужно установить проект (если не указан, используется имя пакета), и версия (будет использована последняя, если не указать).

Заключение


Надеюсь, данный список советов и приемов использования оказался для вас полезным. Если мы что-то упустили, расскажите нам об этом, и мы обновим статью. И помните, если вы забыли какие-либо команды или опции, просто загляните в шпаргалку. Happy Composing!

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


  1. symbix
    27.05.2015 14:58
    +2

    Часто слышу аргумент против composer, что, дескать, ставит в зависимость от сторонних бесплатных ресурсов без SLA — не все знают, что можно поднять свою копию Packagist. Он доступен на гитхабе — github.com/composer/packagist


    1. olegf13 Автор
      27.05.2015 15:35

      ставит в зависимость от сторонних бесплатных ресурсов

      Вообще нет, сторонние репозитории будут игнорироваться Composer'ом (см. root-only). Чтобы добавить возможность брать зависимости зависимостей НЕ из Packagist, нужно добавить сторонние репозитории в главный .json файл.

      Или я неправильно вас понял?


  1. rhamdeew
    27.05.2015 16:14
    -1

    Спасибо! Все никак руки не доходили до более детального изучения этого прекрасного инструмента!


  1. glagola
    28.05.2015 15:00
    +2

    Крупные проекты, такие как Symfony и Laravel, уже используют данный подход для инициализации своих «skeleton» приложений, и многие другие также присоединяются.

    Yii2 также использует этот подход
    composer create-project --prefer-dist yiisoft/yii2-app-advanced yii-application