Logos HTML5, CSS3 e Webshims Lib

O PHP é uma das linguagens de programação mais usadas no mundo, isso ninguém pode negar. Mas, em relação a outras, tais como Ruby, Python e Perl, PHP possui uma tremenda desvantagem: não possui um sistema totalmente confiável e unificado para gerenciamento de pacotes. Ruby tem Gems; Python, PIP; Perl, CPAN; e, estendendo um pouco, é possível citar o NPM do Node.js. Mas e o PHP?

O problema da portabilidade

Na verdade, o PHP até tem um sistema de pacotes, o PEAR, mas, convenhamos, trabalhar com o PEAR não é algo divertido ou produtivo (ainda mais se levarmos em consideração os exemplos das outras linguagens). Para começar, o processo de entrada de pacotes no PEAR é muito burocrático e dificultoso; depois, muitos, muitos pacotes no PEAR estão desatualizados, alguns com códigos de mais de 6 anos atrás que nunca foram atualizados; também, o próprio processo de instalação e atualização de pacotes dependentes possui algumas falhas estruturais que pode fazer com que todo um projeto deixe de funcionar ao atualizar um mísero pacote. Conclusão: PEAR sucks (e PEAR2, também)! O próprio fato de nem o Zend Framework usar PEAR já mostra muita coisa…

Por falar em frameworks, os mais conhecidos fazem sua parte ao tentar prover maneiras fáceis de suas respectivas comunidades reaproveitarem códigos, tentando esquematizar repositórios próprios de pacotes. Para citar alguns:

Mas, mesmo assim, não é bem a solução “ideal”. Quem estava trabalhando numa biblioteca no CakePHP e teve que portar para CodeIgniter (exemplo), sabe do que eu estou falando… Todos são códigos PHP, mas, caso seja preciso que algo funcione de um para outro, geralmente é preciso muito retrabalho! Ao invés de simplesmente jogar os arquivos dentro do projeto e começar a trabalhar, horas e horas são desperdiçadas para migrar uma solução pronta.

Teoricamente, frameworks estão aí para ajudar e prover soluções flexíveis para problemas comuns e bases de código úteis (e a maioria, realmente, cumpre este objetivo). Mas, idealmente falando, não se deveria ficar “preso” a alguma estrutura de códigos: a melhor ferramenta é a que funciona e pode variar para cada situação. Muita gente já deixou (e deixa) de experimentar novas soluções de framework, por exemplo, devido todo o trabalho de “adaptação” e não possibilidade de portar recursos/soluções.

E mesmo falando em código “puro”, o problema continua. É muito comum procurarmos soluções no PHP Classes, Google Code ou SourceForge, mas, apesar de a iniciativa de termos um padrão de codificação que permita a portabilidade de códigos PHP já existir – inclusive para “dentro” de frameworks -, ainda não é algo que está sendo implementado amplamente e tem uso “de fato”.

Composer: a luz no fim do túnel

E é aí que entra em cena o Composer. Conforme pode ser lido no próprio site oficial do Composer:

Composer é uma ferramenta para gerenciamento de dependências em PHP. Ele permite que você declare as bibliotecas dependentes que seu projeto precisa e as instala para você.

Para quem não está acostumado ou nunca ouviu falar em Gerenciamento de Dependências, pode não ter ficado claro (ou difícil de entender por ser bom demais para ser verdade), mas, na prática, o que acontece é que, usando Composer, você simplesmente especifica quais pacotes (códigos reutilizáveis) seu projeto precisa – podendo estes pacotes também ter dependências – e ele vai, automaticamente, baixar isso e incluir nos locais apropriados de seu projeto!

Caso seja preciso acrescentar, remover ou atualizar algum pacote, sem problemas: o gerenciador também faz o trabalho todo! Acreditem: depois que se começa a trabalhar usando este tipo de ferramenta, realmente é difícil abrir mão de suas facilidades e comodidades; além disso, a produtividade vai às alturas – e é isso, mesmo, que todos os programadores queremos, não é verdade?

Nils Adermann e Jordi Boggiano, os “cabeças” do Composer, certamente marcaram seus nomes na história ao dar início ao desenvolvimento e tornar o Composer um projeto open source com o intuito de beneficiar toda a comunidade de programadores PHP.

Como funciona o Composer

O Composer funciona, basicamente, através de duas vertentes: um repositório para os pacotes (Packagist) e instruções via linha de comando para gerenciamento dos pacotes (para procurar, instalar, atualizar, remover, etc).

A instalação dos pacotes é feita por projeto e, por default, nada é instalado globalmente. Por isso o Composer é considerado mais um Gerenciador de Dependências do que um Gerenciador de Pacotes (mas usar o termo “pacotes”, no caso, também não é errado).

Depois de configurar corretamente o arquivo composer.json para instalar as dependências informadas – através do comando install, no Terminal – é feita uma verificação para ver se há algum erro de sintaxe, acontece a busca no repositório pelo pacote informado, o download é realizado e a “instalação” feita no diretório apropriado – por padrão, é o diretório vendor, na raiz do projeto, mas isso também é configurável.

O primeiro passo para entrar no mundo de gerenciamento de pacotes PHP é instalar o Composer – e é altamente desejado você conhecer PHP OO, Namespaces e ter uma noção das PSR-0.

Instalando o Composer

Para ilustrar o artigo, vamos usar os comandos de um sistema *NIX (se, infelizmente, estiver num ambiente Windows, leia essas instruções e o artigo “Instalando Composer no Windows“). É possível instalar o Composer em cada projeto ou ter acesso a ele em qualquer parte do sistema (instalação global). Claro que a última opção é a mais prática, então, para realizar a instalação, execute os seguintes comandos no seu Terminal:

Dessa forma, você terá acesso ao comando composer sempre que preciso.

composer.json

Um dos principais arquivos para se trabalhar com Composer é o composer.json. É nele que as instruções sobre os pacotes que serão usados no projeto ficam contidas. Este é um arquivo “.json” comum que deve ficar na raiz de seu projeto. Existe uma gama de parâmetros possíveis para o gerenciamento de dependências, mas o mais usado, certamente, é o require.

A diretiva “require” no composer.json informa ao Composer quais os pacotes necessários para o projeto. Como citado, o repositório central é o Packagist, então, apesar de ser possível trabalhar com outras “fontes de pacotes”, por padrão é lá que os pacotes que você vai usar estão.

Usando como exemplo o pacote GravatarLib, para integrar seu projeto com o Gravatar, após realizar uma busca, o encontramos no Packagist. Vamos informar ao Composer que a GravatarLib fará parte do gerenciamento de dependências inserindo o seguinte no arquivo composer.json (que deve ficar na raiz do projeto):

Existe toda uma regra de sintaxe para informar ao Composer qual é a versão do pacote que se quer trabalhar. Para mais informações, consulte a seção específica na documentação.

É hora de instalar os pacotes. Vá até o diretório em que está seu projeto no Terminal e execute:

E pronto! O download das dependências vai acontecer automaticamente, estas serão colocadas em suas respectivas pastas e o Composer continuará com o restante do trabalho ao gerar o arquivo composer.lock.

Composer: tela de um exemplo de instalação de pacote

composer.lock

Depois de instalar as dependências informadas, o Composer vai criar automaticamente, também na raiz do projeto, o arquivo composer.lock, com informações de quais pacotes estão instalados e quais as versões destes pacotes.

Isso é importante para garantir a integridade do projeto, pois, quando se especifica a versão de um pacote usado, quando alguém mais da equipe baixar os arquivos para mexer e executar a instalação dos pacotes, é garantido que vai trabalhar com a mesma versão que você e que erros não serão ocasionados em função disso.

É importante fazer commit do composer.json no controle de versões!

Atenção ao alerta acima, pois commitar esse arquivo garante que todos da equipe estarão trabalhando com os mesmos pacotes, nas mesmas versões.

Em relação ao composer.lock, nem sempre é preciso. Como consta no manual oficial do Composer:

Para sua biblioteca, você pode commitar o arquivo “composer.lock” se quiser. Isso pode ajudar sua equipe a sempre testar nas mesmas versões das dependências. No entanto, este arquivo de bloqueio não terá qualquer efeito sobre outros projetos que dependam dele. Ele só surte efeito no projeto principal.

Se você não quiser commitar o arquivo de bloqueio e estiver usando git, adicione-o ao “.gitignore”.

Mas muitos preferem commitar o composer.lock também. Suas dependências podem ter dependências e, como você não sabe exatamente como estas foram especificadas por seus respectivos vendors, se o composer.lock estiver presente ele garantirá que as versões específicas usadas serão as mesmas.

Em compensação, você não precisa adicionar ao controle de versões seu diretório vendors (que é onde, por padrão, o Composer instala os pacotes), pois não é preciso lotar o projeto com esses códigos que podem ser gerados (baixados) quando a pessoa atualizar suas dependências no Composer.

autoload.php

Então, depois de corretamente instalados os pacotes e o arquivo composer.lock ser gerado, é preciso “ensinar” ao seu projeto como autocarregar as dependências para que sejam usadas quando necessário. Não se preocupe, é muito simples:

Com isso, basta usar os pacotes em seu projetos (conforme a instrução de cada “vendor” em nos respectivos sites dos projetos). Por exemplo, para exibir um Gravatar, basta usar:

Revisão

Assim como qualquer novo conhecimento que estamos adquirindo, o gerenciamento de dependências no PHP pode ser um pouco complicado no início (ainda mais ao estudar os vários parâmetros que o Composer oferece). Mas, depois de algum tempo, você verá que tudo ficará mais fácil.

Revisando:

Olhando, assim, parece mais fácil, hã? :-)

E, caso não tenha ficado claro sobre gerenciamento de dependências, se você quiser, por exemplo, excluir um pacote, basta deletar sua referência do arquivo composer.json e mandar o Composer atualizar:

Quando ele não detectar mais a presença do pacote na diretiva require, vai, imediatamente, “desinstalá-lo”.

Então, fica assim:

Screencast

E, para facilitar a fixação desta introdução ao Composer, assista a este screencast e veja tudo acontecendo na hora!

Conclusão

Sem sombra de dúvidas, o PHP e sua comunidade dá um grande passo com o advento do Composer. Gerenciar pacotes agora é tão simples quanto escrever algumas poucas linhas de código num arquivo .json e executar comandos simples no Terminal.

Se você também quer fazer parte dessa evolução, não perca mais tempo e comece a usar o Composer agora mesmo! Estude mais sua documentação para saber de seus outros superpoderes; explore os pacotes do Packagist para encontrar aquele que pode ser usado em seu(s) projeto(s); consulte a referência interativa Composer Cheat Sheet for Developers; fique ligado no blog para acompanhar novos artigos sobre o Composer e; quando já estiver mais à vontade com essa história toda de Gerenciamento de Dependências PHP com Composer, dê sua contribuição e submeta seu pacote no Packagist!

A comunidade agradece!