Содержание


Обновленный PHP

Инструмент Composer для манипулирования зависимостями в PHP

Познакомьтесь с мощным инструментом с открытым исходным кодом для сборки PHP-проектов из сторонних библиотек

Comments

Серия контента:

Этот контент является частью # из серии # статей: Обновленный PHP

Следите за выходом новых статей этой серии.

Этот контент является частью серии:Обновленный PHP

Следите за выходом новых статей этой серии.

В связи с повышением уровня зрелости языка PHP созданные с его помощью приложения радикально усложнились. Современные PHP-разработчики нередко опираются на сторонние библиотеки, помогающие быстрее создавать проекты программного обеспечения. Например, приложение размером с Facebook невозможно было бы создать без использования хорошо сопровождаемых сторонних библиотек, доступных сегодня для PHP. Однако преимущества повторного использования программного обеспечения идут рука об руку с издержками: разработчику нужно управлять не только списком библиотек, которые требуются для каждой установки его приложения, но также и деревом зависимостей, которое образуется вследствие того, что каждая используемая разработчиком библиотека базируется на других библиотеках. Как образом разработчику управлять сложной и взаимозависимой совокупностью множества библиотек?

Два решения для манипулирования зависимостями, которые PHP-разработчики широко использовали в прошлом, уже пережили пик своей эффективности. Разработчику приходилось проверять каждую необходимую ему библиотеку в своем репозитарии управления версиями вместе со своим программным кодом. Этот механизм работал до определенной степени, однако зачастую порождал больше трудностей, чем устранял. Разработчику приходилось сопровождать собственную локальную версию соответствующей библиотеки. Кроме того, ему нужно было вручную реализовать все имеющиеся доступные исправления ошибок для этой библиотеки, загружая новые версии и вводя ее в репозитарий. В итоге у разработчика образовывался объемный журнал изменений в системе управления версиями, который не имел никакого отношения к его реальному коду. В результате библиотеки обычно продолжали использоваться в тех версиях, которые они имели в начале проекта, и редко подвергались обновлениям.

Проект PEAR (PHP Extension and Application Repository) среди прочего имел целью устранить и эту проблему. PEAR предоставляет набор работающих совместно библиотек, допускающих расширение программистами. PEAR также включает инструменты командной строки для установки нужных разработчику библиотек вместе с их зависимостями (если таковые имеются в наличии). На протяжении долгого времени использование репозитария PEAR было наилучшим подходом, имевшим большое количество сторонников, однако у этой системы есть и недостатки.

Установки PEAR-библиотек хранятся на глобальном уровне, в операционной системе. Хотя такая организация избавляет разработчика от необходимости регистрации библиотек в репозитарии управления версиями, она порождает больше проблем, чем устраняет. Разработчик никогда не знает точно, какие версии библиотеки исполняются на используемой им системе. Эта путаница зачастую становилась источником ложных ошибок. Например, после установки своего приложения на новом сервере разработчик мог столкнуться с претензиями относительно работоспособности приложения. В конечном итоге разработчик понимал, что на этом сервере попросту не было надлежащих PEAR-библиотек. Кроме того, ему требовался доступ, чтобы установить эти глобальные библиотеки (с этой проблемой приходилось сталкиваться многим пользователям общего хостинга).

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

Брайан Керниган (Brian Kernighan)

В апреле 2011 года PHP-разработчики Нильс Адерманн (Nils Adermann) и Джорди Боджиано (Jordi Boggiano) пришли к выводу, что PHP требуется новое решение для работы с зависимостями, и приступили к созданию соответствующего инструмента. Первого марта 2012 года они выпустили инструмент под именем Composer. При использовании Composer разработчик создает конфигурационный файл, определяющий сторонние библиотеки, в которых нуждается его приложение (независимо от того, где они размещены). Затем он запускает Composer, чтобы полностью скомпоновать (compose) свое приложение. Composer загружает все указанные разработчиком библиотеки, а также все зависимости этих библиотек. В статье излагаются основные сведения о Composer и демонстрируется использование этого инструмента в PHP-проектах.

Установка программного обеспечения Composer

Инструмент Composer способен работать на различных платформах. Установка на любом компьютере под управлением UNIX® или Linux® не составляет никаких трудностей. Пользователь может осуществить локальную установку, запустив программу-установщик с помощью утилиты curl непосредственно в среде PHP.

 curl -sS https://getcomposer.org/installer | php

Показанная выше команда создает установку инструмента Composer в локальном исполняемом файле composer.phar. Чтобы сделать эту установку доступной глобально из любого места вашей системы, скопируйте файл composer.phar в каталог с соответствующим маршрутом, как в данном примере (возможно, вам придется с помощью утилиты sudo предоставить самому себе разрешение на запись в корневые каталоги).

 mv composer.phar /usr/local/bin/composer

Теперь команду composer можно выполнить из командной строки в любом месте системе.

На компьютере под управлением Windows® ручная установка более сложна, поэтому создатели Composer разработали программу-установщик, которую вы можете загрузить и запустить на исполнение. После установки инструмента Composer с ним можно будет взаимодействовать с помощью командной строки Windows.

Базовые сведения об использовании

Composer – это мощный инструмент с удивительным набором возможностей. Тем не менее обычно вы будете использовать этот инструмент для создания/загрузки/установки программного кода для сторонних PHP-приложений или инфраструктур на основе конфигурации, предоставленной соответствующей третьей стороной. Например, с помощью Composer можно установить инфраструктуру Zend Framework и все ее зависимости. Запустите Composer с помощью команды install, и Composer сам сделает все остальное.

Если вы установили Composer глобально (или в среде Windows), выполните следующую команду:

 composer install

Если вы установили Composer локально только для одного приложения, выполните следующую команду:

 php composer.phar install

В примерах для остальной части этой статьи предполагается, что мы установили Composer глобально.

В дополнение к загрузке всех библиотек, необходимых вашему проекту/приложению, Composer также предоставляет удобный способ включения всех этих библиотек. Он устанавливает все библиотеки в папку с именем vendor, чтобы отличить их от кода вашего собственного проекта. В папке vendor Composer создает файл с именем autoload.php. Результатом включения этого файла в ваш проект является настройка автозагрузчика для всех библиотек, которые инструмент Composer загрузил для вас:

 require 'vendor/autoload.php';

Каким образом инструмент Composer находит библиотеки

Чтобы загрузить для вас пакеты библиотек, инструменту Composer для начала нужно знать, где найти эти пакеты. Эта информация предоставляется репозитариями Composer: это онлайновые источники, содержащие сведения о доступных в Интернете пакетах, о способах их извлечения и об их собственных зависимостях. Любой разработчик может поддерживать свой собственный репозитарий для предоставления доступа к внутренним библиотекам (а веб-сайт Composer предоставляет для этого соответствующие инструкции), однако основным репозитарием, который вы будете использовать, является репозитарий Packagist. Репозитарий Packagist предоставляет пакеты для большинства PHP-проектов с открытым исходным кодом. Вы можете обратиться в этот репозитарий, чтобы найти нужные вам библиотеки.

Библиотеки программного обеспечения далеко не всегда хорошо работают вместе. Связующим звеном для всех библиотек Packagist является организация PHP-FIG (PHP Framework Interop Group; первоначально эта организация носила название PHP Standards Group), созданная на конференции php[tek] 2009. Организация PHP-FIG – участники которой представляют многочисленные популярные PHP-приложения и PHP-инфраструктуры — была сформирована с целью выявления путей для улучшения совместной работы проектов этих участников. Кульминацией этого сотрудничества стало создание документов типа PHP Standards Recommendation (PSR), описывающих дополнительные стандарты для библиотек. Библиотеки, реализующие эти единые стандарты, способны взаимодействовать в рамках общего набора требований.

Самыми важными являются документы PSR-0 и PSR-4, обеспечившие создание инструмента Composer. В этих документах описывается общий метод именования для классов и пространств имен, а также указания по отображению этих имен на файлы в файловой системе. В свою очередь, общий интерфейс autoloader способен загружать классы из любой нужной библиотеки. Именно создание общего стандартизованного способа, позволяющего библиотекам совместно использовать свои классы без взаимного перезаписывания, позволило инструменту Composer стать столь эффективным.

Конфигурирование инструмента Composer для собственных проектов пользователя

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

Сначала я напишу новый PHP-проект — небольшую программу, которая преобразует Markdown-файлы в формат HTML. Поиск в репозитарии Packagist по ключевому слову markdown предлагает библиотеку michaelf/php-markdown в качестве хорошего выбора и показывает URL-адрес начальной страницы этого проекта (рис. 1).

Рисунок 1. Информация о библиотеке в репозитарии Packagist
Screenshot of the michelf/php-markdown listing on Packagist
Screenshot of the michelf/php-markdown listing on Packagist

Чтобы сообщить инструменту Composer, какие файлы следует включить в наш проект, мы создаем конфигурационный файл с именем composer.json. Этот файл в формате JSON может содержать различные команды, однако наиболее распространенной (а часто и единственной) из необходимых вам команд является ключ require. В этот ключ я передаю имя нужного мне пакета и номер версии, которую я буду поддерживать.

 { "require": { "michelf/php-markdown": "1.4.*" } }

Теперь я могу выполнить директиву composer install в каталоге своего приложения. Инструмент Composer потратит несколько минут на загрузку требуемой библиотеки, которую я указал, в каталог vendor, и создаст для меня автозагрузчик, включающий этот каталог. Кроме того, Composer создаст другой файл (с именем composer.lock), который я опишу несколько позже. Команды и выходная информация имеют следующий вид.

 > ls composer.json > composer install Loading composer repositories with package information Installing dependencies (including require-dev) - Installing michelf/php-markdown (1.4.1) Downloading: 100% Writing lock file Generating autoload files > ls -F composer.json composer.lock vendor/

Теперь я могу написать код, опирающийся на пакет michelf/php-markdown. package. Следующий короткий PHP-скрипт сделает все, что мне нужно.

 <?php require 'vendor/autoload.php'; use \Michelf\Markdown; echo Markdown::defaultTransform(file_get_contents("php://stdin"));

Инструмент Composer обеспечивает мне прямолинейное и простое решение. У выбранного мной пакета Markdown нет дополнительных зависимостей, как это иногда бывает. Но если бы я выбрал пакет с зависимостями, инструмент Composer автоматически извлек бы все эти зависимости одновременно и сконфигурировал бы их.

Указание версий

В файл composer.json можно включить столько библиотек, сколько требуется вашему программному обеспечению, и для каждой из них указать нужную вам версию. Указание версий – это одно из важных условий, соблюдение которых гарантирует постоянную работоспособность вашего программного обеспечения. С помощью группового символа в номере версии вы даже можете разрешить инструменту Composer обновлять библиотеки от вашего имени. В предыдущем примере я указал версию как "1.4.*". Теперь при каждом исполнении команды composer install инструмент Composer найдет последний выпуск версии 1.4 библиотеки, но не будет принимать версии 1.5, 2.0 или какие-либо другие более высокие версии. Если бы я хотел всегда получать последнюю версию библиотеки, я мог бы указать номер версии как "*" (хотя потенциально это может вызвать проблемы, если изменится обеспечивающий API-интерфейс).

В таблице 1 показан полный перечень опций, которые можно использовать при указании ограничений на версии.

Таблица 1. Ограничения на версии пакета
СпецификацияПримерОписание
Точный номер версии1.0.2Точный номер версии пакета.
Диапазон>=1.0>=1.0 <2.0>=1.0 <1.1 || >=1.2Для задания диапазона допустимых версий можно использовать операторы сравнения Допускаются следующие операторы: >, >=, <, <=, !=. Можно определить несколько диапазонов; по умолчанию эти диапазоны связаны логическим оператором И, при наличии разделителя (||) они связаны логическим оператором ИЛИ.
Диапазон, определяемый дефисом1.0 - 2.0Набор версий (включая конечные значения).
Групповой символ1.0.*Шаблон с групповым символом *. 1.0.* эквивалентно >=1.0 <1.1.
Оператор ~~1.2.3"Следующий большой выпуск". Разрешает увеличение последней цифры; соответственно, пример слева эквивалентен выражению >=1.2.3 <1.3.0. Последняя цифра может возрастать.
Оператор ^^1.2.3"Следующий большой выпуск". Подобен оператору ~, но допускает семантическое управление версиями и разрешает все изменения до следующей базовой версии; соответственно, пример слева эквивалентен выражению >=1.2.3 <2.0.

Стабильность пакета

Другое соображение относительно конфигурирования инструмента Composer на предмет получения именно тех библиотек, которые нужны вашему проекту, состоит в том, насколько стабильными, по вашему мнению, должны быть выпуски соответствующей библиотеки. Если вам нужна самая современная версия или вы хотите принять участие в тестировании программного обеспечения, вы можете запросить бета-версию пакета или его ветвь разработки. Флаг стабильности задается путем его добавления в конец строки require с символом @. Например, запросить последнюю версию ветви разработки пакета PHPUnit можно следующим образом:

 { "require": { "phpunit/phpunit": "4.8.*@dev" } }

В качестве справочной информации репозитарий Packagist показывает, какие ветви существуют и какую строку нужно использовать, чтобы обратиться к ним (рис. 1).

Блокировка версий

Одно из важных достоинств Composer состоит в том, что разработчику не требуется включать сторонние библиотеки в свою систему управление версиями. При публикации новой установки своего программного обеспечения вы можете сохранить в чистоте систему управление версиями, позволив инструменту Composer загрузить и сконфигурировать все библиотеки для вас. Однако при этом вы можете столкнуться с проблемами. Предположим, что для вашего веб-сайта одновременно работают 20 серверов, на которых используются разные версии библиотек, поскольку развертывание программного кода (и выполнение команды composer install) осуществлялись в разные моменты времени. Или предположим еще более простую ситуацию, когда несколько разработчиков имеют разные библиотеки и неспособны воспроизводить ошибки друг друга. Последствия этого могут оказаться катастрофическими.

Инструмент Composer предоставляет решение для этой проблемы. Как уже говорилось (см. раздел "Конфигурирование инструмента Composer для собственных проектов пользователя"), при первом исполнении команды composer install создается файл composer.lock. Этот файл точно указывает, какие библиотеки, включая их конкретные версии, были загружены и установлены. Когда вы передаете свой проект в программную систему управления версиями, передавайте файл composer.lock, но не каталог vendor. Когда новое развертывание кода будет подготовлено и команда composer install запущена, инструмент Composer сначала будет искать lock-файл. Если он найдет этот файл, то установит точный дубликат исходной установки, что гарантирует единообразие ваших установок.

Конечно, необходим способ перехода к более новым версиям кода — желательно, чтобы это было нечто лучшее, чем удаление lock-файла и всего каталога vendor. Composer предоставляет такой способ в виде команды update. Когда вы запускаете команду composer update, Composer сравнивает версию программного обеспечения, установленного при посредстве lock-файла, с последней конфигурацией в JSON-файле. Если доступны более новые версии программного обеспечения, которые допускает ваша конфигурация (или если после последней установки к этой конфигурации были добавлены новые библиотеки), Composer загружает новые библиотеки и конфигурирует их "по месту".

Создание автозагрузчика для собственных классов пользователя

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

В следующем примере я обновляю предыдущий файл composer.json, чтобы создать свой собственный автозагрузчик.

 { "require": { "michelf/php-markdown": "1.4.*" }, "autoload": { "psr-4": {"Converter\\": "src/"} } }

В этом примере я задаю пространство имен Converter и указываю, что все файлы классов для этого пространства имен существуют внутри относительного каталога с именем src. Таким образом, если у меня есть класс с именем Converter\CommandLine, автозагрузчик будет искать этот класс, чтобы сохранить его в файловой системе как src/CommandLine.php. Теперь этот файл является совместимым со стандартом PSR-4 автозагрузчиком, который был сгенерирован для меня.

Предоставление собственных пакетов

На этом этапе я могу предоставить приложение для преобразования из Markdown в HTML в виде пакета для репозитария Packagist (поскольку это именно приложение, а не библиотека, допускающая многократное использование, то предоставление его в виде пакета на самом деле не имеет большого смысла, — однако в этом упражнении мы притворимся, что на самом деле это библиотека). По существу после создания моего файла composer.json это приложение является самостоятельно пакетом и может быть установлено. Имя этого пакета должно быть представлено в формате vendor/package. Таким образом, в моем случае я добавляю в конфигурационный файл следующую строку:

 "name": "EliW/Converter",

Имеет смысл добавить и несколько других конфигурационных настроек. Мы может задать требуемую версию PHP как виртуальное имя пакета, которое Composer будет принудительно применять. (Среди многих других опций вы можете принудительно задать номера версий, чтобы не позволить инструменту Composer принимать стандартные шаблоны системы управления версиями. Вы также можете предоставить метаданные, чтобы список пакетов выглядел завершенным.) В следующем примере я указываю номер версии PHP и представляю мое приложение-конвертер в виде самодостаточного полного пакета.

 { "name": "EliW/Converter", "require": { "michelf/php-markdown": "1.4.*", "php": ">=5.3.0" }, }

Итак, конфигурирование успешно выполнено. После передачи моего приложения в какую-либо онлайновую систему управления версиями (например, в GitHub) я могу войти в систему со своей учетной записью Packagist и представить информацию о моем пакете, чтобы сделать это приложение доступным для включения в проекты других разработчиков.

Заключение

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

В статьях данного цикла я показал, до какого уровня эволюционировал сам язык PHP, как он удовлетворяет современным требованиям к защите и как он использует современные системы управления зависимостями и управления пакетами, чтобы справиться с непрерывно растущей сложностью современного программного кода. В следующей статье я рассмотрю возможности, которые современная экосистема PHP предоставляет разработчикам для управления своими средами разработки и развертывания с помощью инструментов Vagrant и PuPHPet.


Ресурсы для скачивания


Похожие темы


Комментарии

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Web-архитектура, Open source
ArticleID=1023844
ArticleTitle=Обновленный PHP: Инструмент Composer для манипулирования зависимостями в PHP
publish-date=12112015