Composer na prática: instalando, atualizando e lockfile
1. Introdução ao Composer e seu papel no ecossistema PHP
O Composer é, sem dúvida, uma das ferramentas mais importantes para o desenvolvimento PHP moderno. Antes dele, gerenciar bibliotecas de terceiros era um processo manual e propenso a erros: os desenvolvedores baixavam arquivos, colavam em pastas e configuravam includes manualmente. O Composer mudou esse cenário ao introduzir um gerenciador de dependências robusto, similar ao que npm representa para JavaScript ou Bundler para Ruby.
Com o Composer, você declara as bibliotecas que seu projeto precisa em um arquivo chamado composer.json, e ele se encarrega de baixar as versões corretas, resolver dependências transitivas e configurar o autoloading. O fluxo de trabalho básico envolve três elementos principais:
- composer.json: arquivo de configuração que define as dependências e suas restrições de versão
- composer.lock: snapshot exato das versões instaladas (fundamental para reprodutibilidade)
- pasta vendor/: diretório onde as dependências são baixadas e o autoloading é gerado
2. Instalação do Composer e configuração inicial
A instalação do Composer pode ser feita globalmente no sistema. No Linux e macOS, o método mais comum é via terminal:
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
sudo mv composer.phar /usr/local/bin/composer
No Windows, o instalador gráfico disponível em getcomposer.org é a opção mais prática. Após a instalação, verifique com:
composer --version
Para iniciar um projeto, você pode criar o composer.json manualmente ou usar o comando interativo:
composer init
Este comando faz perguntas sobre o projeto (nome, descrição, autor, etc.) e gera um arquivo inicial. A estrutura básica do composer.json contém a seção require para dependências de produção e require-dev para ferramentas de desenvolvimento:
{
"name": "meu/projeto",
"require": {
"monolog/monolog": "^2.0",
"guzzlehttp/guzzle": "~7.0"
},
"require-dev": {
"phpunit/phpunit": "^9.5"
}
}
Os operadores de versão merecem atenção:
- ^2.0: permite atualizações até a próxima versão major (2.x.x, mas não 3.0.0)
- ~7.0: permite apenas patches (7.0.x)
- *: qualquer versão (não recomendado para produção)
3. Instalando dependências com composer install
Quando você executa composer install, o Composer primeiro verifica se existe um arquivo composer.lock. Se existir, ele lê as versões exatas de lá e as instala. Se não existir, ele resolve as dependências a partir do composer.json e gera o lockfile.
composer install
Para instalar apenas dependências de produção (ignorando require-dev), use a flag --no-dev:
composer install --no-dev --optimize-autoloader
Isso é especialmente útil em ambientes de produção, onde ferramentas de teste não são necessárias. Ao final da instalação, a pasta vendor/ conterá todas as bibliotecas baixadas, e o arquivo vendor/autoload.php será gerado automaticamente, permitindo o carregamento automático das classes:
<?php
require_once __DIR__ . '/vendor/autoload.php';
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
$log = new Logger('meu_app');
$log->pushHandler(new StreamHandler('app.log', Logger::WARNING));
$log->warning('Exemplo de log com Monolog');
4. O lockfile (composer.lock) e sua importância
O composer.lock é um arquivo JSON que registra as versões exatas de todas as dependências instaladas, incluindo as dependências transitivas. Ele funciona como um "instantâneo" do estado do projeto em um determinado momento.
A principal razão para versionar o composer.lock no Git é garantir reprodutibilidade. Imagine que sua equipe tem 5 desenvolvedores e um servidor de CI/CD. Sem o lockfile, cada execução de composer install poderia resolver versões ligeiramente diferentes, causando bugs difíceis de rastrear. Com o lockfile versionado, todos usam exatamente as mesmas versões.
# Adicione o lockfile ao repositório
git add composer.lock
git commit -m "Adiciona lockfile para garantir versões consistentes"
A pasta vendor/, por outro lado, não deve ser versionada. Adicione-a ao .gitignore:
/vendor/
5. Atualizando dependências com composer update
Enquanto composer install respeita o lockfile, composer update o ignora e resolve novamente as dependências, atualizando o composer.lock com as novas versões que respeitam as constraints definidas no composer.json.
# Atualiza todas as dependências
composer update
# Atualiza apenas um pacote específico
composer update monolog/monolog
A principal diferença prática é: use composer install em ambientes de produção e no dia a dia da equipe (para manter consistência), e use composer update quando você ativamente quiser atualizar versões.
As constraints de versão no composer.json determinam o limite das atualizações. Se você definiu "monolog/monolog": "^2.0", o composer update só atualizará para versões 2.x, nunca para 3.0. Para atualizar para uma nova versão major, você precisa alterar manualmente a constraint no composer.json.
6. Resolvendo conflitos e problemas comuns
Conflitos de dependência são inevitáveis em projetos complexos. Quando duas bibliotecas exigem versões incompatíveis de uma mesma dependência, o Composer exibe mensagens de erro detalhadas.
Para rastrear por que um pacote está sendo exigido:
composer why monolog/monolog
Para verificar por que uma versão específica não pode ser instalada:
composer why-not monolog/monolog 3.0
Se o cache do Composer causar problemas, limpe-o e reinstale as dependências do zero:
composer clear-cache
rm -rf vendor composer.lock
composer install
7. Boas práticas para o dia a dia com Composer
Além de versionar o composer.lock e ignorar vendor/, algumas práticas melhoram a experiência:
Scripts personalizados no composer.json automatizam tarefas comuns:
{
"scripts": {
"post-install-cmd": [
"php artisan cache:clear"
],
"post-update-cmd": [
"php artisan optimize"
],
"test": "phpunit"
}
}
Para executar: composer test
Autoloading otimizado para produção reduz o tempo de carregamento das classes:
composer dump-autoload -o
Isso gera um autoloader com mapas de classe otimizados, eliminando a necessidade de varrer diretórios em cada requisição.
Por fim, mantenha o composer.json organizado, com dependências bem definidas e versões explicitamente controladas. Isso facilita a manutenção e evita surpresas desagradáveis em atualizações futuras.
Referências
- Documentação oficial do Composer — Guia completo de instalação, uso e configuração do Composer
- Composer: gerenciamento de dependências em PHP (PHP.net) — Visão geral oficial do PHP sobre o Composer
- Entendendo o composer.lock (Medium - DevPorAi) — Artigo prático sobre a importância do lockfile
- Boas práticas com Composer em produção (Laravel News) — Dicas para usar o Composer em ambientes de produção
- Resolvendo conflitos de dependência no Composer (Stack Overflow) — Discussão técnica sobre resolução de conflitos com exemplos reais
- Composer: scripts e automação (SymfonyCasts) — Tutorial em vídeo sobre scripts personalizados no Composer