PHP Composer: личные впечатления

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

Возьмём к примеру Ruby. Этот язык, блин, ну просто законодатель мод в сфере веб-дева. Там и удобные инструменты скаффолдинга (ну в ZF это тоже есть), и такие штуки, как rake для выполнения задач. Я уж не говорю про миграции, юнит-тесты со всяческими mock-объектами. Когда я кодил на Ruby ощущение было сродни тому, что сидишь в комфортабельном кресле в бизнес-классе в самолете и единственной твоей проблемой является выбор напитка под настроение.

Шучу-шучу. Не всё так радужно в Ruby 🙂 Есть куча кривых гемов, разработчики иногда выпускают такооое чудо, что мама не горюй. Я уж молчу про низкоуровневое шаманство, когда надо сделать что-то типа распределённой или многопоточной системы. Но речь в посте будет не об этом. А о том, что в Ruby есть такая штук, как RubyGems.

RubyGems это система для управления зависимостями в Ruby проекте. В частности есть такая штука как Bundler, который одним движением устанавливает нужные пакеты или обновляет их. Именно с него наглым образом был списан он послужил вдохновением для Composer.

Что умеет Composer

 

Итак, краткий обзор фич. Их всего две: управление пакетами и автозагрузка классов. Надо сказать, что без composer обе эти задачи отнимали достаточно много времени. Интернет до сих пор пестрит статьями в стиле “как связать ZF 1.x и Doctrine 2” или “как установить Doctrine 2 ODM и Doctrine 1 ORM”. Извращение, скажет вы. Я спеуиально утрировал, но согласитесь, приходится довольно сильно заморачиваться чтобы скрестить некоторые фреймворки или библиотеки. С выходом Composer ситуация поменялась.

Отдельное спасибо надо сказать за человеческую автозагрузку. Ух сколько времени я когда-то потратил на интеграцию Zend_Loader_Autoloader и Doctrine/ClassLoader. Теперь это в прошлом. Садимся в кресло 🙂

Пример composer.json

 

Вот пример файла с описанием зависимостей из одного проекта.

Итак, давайте пройдёмся построчно. В блоке require мы описываем название пакетов в виде vendorName/packageName и минимально необходимые версии для нашего проекта. Потом они будут сами скачиваться и устанавливаться в папку vendor. Как видите Доктрина например раскукожилась сразу в несколько пакетов. Кстати миграции в отдельный пакет выделились совсем недавно, так что следите за новостями проекта. Товарищу simukti выражаю огромную благодарность, за то что он портировал все последние версии ZF 1.x в composer. Когда мне в своё время он понадобился, я начал это делать… да так и не успел в связи с другими задачами. Сейчас же в рамках одного проекта у нас есть возможность использовать компоненты Doctrine 2 ODM + ORM + ZF 1.x + ZF 2.x. Сумасшедший винигрет, но нам он нужен. Т.к. мы потихоньку мигрируем с MySQL (да простит меня Michail Widenius) на MongoDB. Основной костяк – на ZF1, ну а ZF2 – тоже не из праздного любопытсята /* интрига */.

Теперь вторая часть конфига – require. Тут мы задаём классы (вернее их неймспейсы) и места их хранения, т.е. разрешаем пути для соответствующих неймспейсов. Обратите внимание  на несколько моментов. Для гидраторов доктрины (если вы не знаете что это, то можете пропустить) указываем пути, т.к. при отсутствующем автозагрузчике доктрины она не может их найти. Последняя строка – местоположение помойки, где могут лежать классы с любыми неймспейсами. Основная особенность Composer в том, что такая помойка (к счастью) может быть только одна. А вот в нашем проекте классы require’ились откуда попало, поэтому пришлось провести так сказать garbage collection и свалить всё в одну кучу. Придётся конечно когда-нибудь и её разобрать, но теперь по крайней месте весь мусор в одном месте. Ну а ZendExtra и DoctrineExtra – этомои расширения, котоыре я частично описывал в своих постах.

Баги Composer

 

Ну куда же без багов. Самый пожалуй замечатенльный баг fatal: No such remote ‘composer’. Когда вы, уверенные, что у вас всё ок, делаете php composer.phar update, вас ждёт … разочарование.  Пробелема в том, что composer не выкачивает исходники (вернее не обновляет их) если указана dev ветка, и исходники старше 6 месяцев. К сожалению в моём composer.json такими оказались пакеты с доктриной. Решение простое, перед тем, как делать update удаляем пакеты с доктриной.

Второй баг был в том, что в репозитарийх некоторых пакетов лежит файл .gitignore, который выкачивается при update/install. А если потом исходники проекта (вместе с этим пакетом) закоммитить, то они не дойдёт. Например в assembla, с которйо я работаю появляется некий пустой файл вместо папки с сорцами. При этом коммит и пуш проходит нормально, а траварищи жалуются, что к ним ничего не прилетает. Решение простое, после Update стираем наифг файлы .gitignore из изходников с пакетами.

Использовать или нет Composer?

 

Да! Как сказал кто-то, ваша библиотека – отстой, если в её корне не лежит файл composer.json Не ну серьезно, прошли времена php 4, phpclasses, кучи автозагрузчиков в стеке. Давайте перестанем плодить говнокод, будем соблюдать стандарты (ну хотя бы psr-0) и писать так сказать код с человеческим лицом. Я всецело за унификацию и стандартизацию! Enjoy!