Composer: dicas de uso

Composer é uma ferramenta para gerenciamento de dependências em PHP. Ele nos permite listar as bibliotecas das quais nosso projeto depende e as instalará e atualizará para nós. Vamos mostrar:

  • como instalar o Composer
  • seu uso em um projeto novo ou existente

Instalação

Composer é um arquivo .phar executável que você baixa e instala da seguinte maneira:

Windows

Use o instalador oficial Composer-Setup.exe.

Linux, macOS

Basta 4 comandos que você pode copiar desta página.

Além disso, colocando-o em uma pasta que esteja no PATH do sistema, o Composer se torna acessível globalmente:

$ mv ./composer.phar ~/bin/composer # ou /usr/local/bin/composer

Uso no projeto

Para começar a usar o Composer em seu projeto, você só precisa do arquivo composer.json. Ele descreve as dependências do nosso projeto e também pode conter outros metadados. Um composer.json básico pode, portanto, parecer assim:

{
	"require": {
		"nette/database": "^3.0"
	}
}

Aqui dizemos que nossa aplicação (ou biblioteca) requer o pacote nette/database (o nome do pacote consiste no nome da organização e no nome do projeto) e quer a versão que corresponde à condição ^3.0 (ou seja, a versão 3 mais recente).

Temos, portanto, o arquivo composer.json na raiz do projeto e executamos a instalação:

composer update

O Composer baixará o Nette Database para a pasta vendor/. Além disso, criará o arquivo composer.lock, que contém informações sobre quais versões exatas das bibliotecas ele instalou.

O Composer gera o arquivo vendor/autoload.php, que podemos simplesmente incluir e começar a usar as bibliotecas sem qualquer trabalho adicional:

require __DIR__ . '/vendor/autoload.php';

$db = new Nette\Database\Connection('sqlite::memory:');

Atualização de pacotes para as versões mais recentes

A atualização das bibliotecas usadas para as versões mais recentes de acordo com as condições definidas em composer.json é responsabilidade do comando composer update. Por exemplo, para a dependência "nette/database": "^3.0", ele instalará a versão 3.x.x mais recente, mas não a versão 4.

Para atualizar as condições no arquivo composer.json, por exemplo, para "nette/database": "^4.1", para que seja possível instalar a versão mais recente, use o comando composer require nette/database.

Para atualizar todos os pacotes Nette usados, seria necessário listá-los todos na linha de comando, por exemplo:

composer require nette/application nette/forms latte/latte tracy/tracy ...

O que é impraticável. Use, portanto, o script simples Composer Frontline, que fará isso por você:

php composer-frontline.php

Criação de um novo projeto

Você pode criar um novo projeto Nette com um único comando:

composer create-project nette/web-project nome-do-projeto

Como nome-do-projeto, insira o nome do diretório para o seu projeto e confirme. O Composer baixará o repositório nette/web-project do GitHub, que já contém o arquivo composer.json, e logo depois o Nette Framework. Deve bastar apenas definir as permissões de escrita nas pastas temp/ e log/ e o projeto deve ganhar vida.

Se você sabe em qual versão do PHP o projeto será hospedado, não se esqueça de configurá-la.

Versão do PHP

O Composer sempre instala as versões dos pacotes que são compatíveis com a versão do PHP que você está usando atualmente (mais precisamente, com a versão do PHP usada na linha de comando ao executar o Composer). O que, no entanto, provavelmente não é a mesma versão que sua hospedagem usa. Por isso, é muito importante adicionar ao arquivo composer.json a informação sobre a versão do PHP na hospedagem. Depois disso, apenas as versões dos pacotes compatíveis com a hospedagem serão instaladas.

Que o projeto será executado, por exemplo, no PHP 8.2.3, definimos com o comando:

composer config platform.php 8.2.3

Assim, a versão será escrita no arquivo composer.json:

{
	"config": {
		"platform": {
			"php": "8.2.3"
		}
	}
}

No entanto, o número da versão do PHP é especificado em outro local do arquivo, na seção require. Enquanto o primeiro número determina para qual versão os pacotes serão instalados, o segundo número diz para qual versão a própria aplicação foi escrita. E de acordo com ele, por exemplo, o PhpStorm define o PHP language level. (Claro, não faz sentido que essas versões sejam diferentes, então a dupla escrita é uma falha de design.) Você define esta versão com o comando:

composer require php 8.2.3 --no-update

Ou diretamente no arquivo composer.json:

{
	"require": {
		"php": "8.2.3"
	}
}

Ignorar versão do PHP

Os pacotes geralmente especificam tanto a versão mais baixa do PHP com a qual são compatíveis quanto a mais alta com a qual foram testados. Se você planeja usar uma versão do PHP ainda mais recente, talvez para fins de teste, o Composer se recusará a instalar tal pacote. A solução é a opção --ignore-platform-req=php+, que faz com que o Composer ignore os limites superiores da versão do PHP exigida.

Mensagens falsas

Ao atualizar pacotes ou alterar números de versão, ocorre que há um conflito. Um pacote tem requisitos que estão em conflito com outro e assim por diante. Mas o Composer às vezes exibe uma mensagem falsa. Ele relata um conflito que realmente não existe. Nesse caso, ajuda excluir o arquivo composer.lock e tentar novamente.

Se a mensagem de erro persistir, então ela é séria e é necessário ler nela o que e como ajustar.

Packagist.org – repositório central

Packagist é o repositório principal no qual o Composer tenta procurar pacotes, a menos que lhe digamos o contrário. Também podemos publicar nossos próprios pacotes aqui.

E se não quisermos usar o repositório central?

Se tivermos aplicações internas da empresa que simplesmente não podemos hospedar publicamente, criaremos um repositório corporativo para elas.

Mais sobre o tema de repositórios na documentação oficial.

Autoloading

Uma característica fundamental do Composer é que ele fornece autoloading para todas as classes instaladas por ele, que você inicia incluindo o arquivo vendor/autoload.php.

No entanto, é possível usar o Composer também para carregar outras classes fora da pasta vendor. A primeira opção é deixar o Composer pesquisar pastas e subpastas definidas, encontrar todas as classes e incluí-las no autoloader. Isso é alcançado definindo autoload > classmap em composer.json:

{
	"autoload": {
		"classmap": [
			"src/",      #  inclui a pasta src/ e suas subpastas
		]
	}
}

Posteriormente, é necessário executar o comando composer dumpautoload a cada alteração e deixar as tabelas de autoloading serem regeneradas. Isso é extremamente inconveniente e é muito melhor confiar esta tarefa ao RobotLoader, que realiza a mesma atividade automaticamente em segundo plano e muito mais rapidamente.

A segunda opção é seguir o PSR-4. Simplificadamente, é um sistema onde namespaces e nomes de classes correspondem à estrutura de diretórios e nomes de arquivos, ou seja, por exemplo, App\Core\RouterFactory estará no arquivo /path/to/App/Core/RouterFactory.php. Exemplo de configuração:

{
	"autoload": {
		"psr-4": {
			"App\\": "app/"   # o namespace App\ está no diretório app/
		}
	}
}

Como configurar exatamente o comportamento pode ser encontrado na documentação do Composer.

Testando novas versões

Você quer testar uma nova versão de desenvolvimento de um pacote. Como fazer isso? Primeiro, adicione este par de opções ao arquivo composer.json, que permite instalar versões de desenvolvimento de pacotes, mas recorrerá a isso apenas se não houver nenhuma combinação de versões estáveis que atenda aos requisitos:

{
	"minimum-stability": "dev",
	"prefer-stable": true,
}

Além disso, recomendamos excluir o arquivo composer.lock, às vezes o Composer inexplicavelmente se recusa a instalar e isso resolve o problema.

Digamos que seja o pacote nette/utils e a nova versão tenha o número 4.0. Você a instala com o comando:

composer require nette/utils:4.0.x-dev

Ou você pode instalar uma versão específica, por exemplo, 4.0.0-RC2:

composer require nette/utils:4.0.0-RC2

Mas se outro pacote depender da biblioteca, que está bloqueada em uma versão mais antiga (por exemplo, ^3.1), então o ideal é atualizar o pacote para que funcione com a nova versão. No entanto, se você quiser apenas contornar a restrição e forçar o Composer a instalar a versão de desenvolvimento e fingir que é uma versão mais antiga (por exemplo, 3.1.6), pode usar a palavra-chave as:

composer require nette/utils "4.0.x-dev as 3.1.6"

Chamada de comandos

Através do Composer, é possível chamar comandos e scripts próprios pré-preparados, como se fossem comandos nativos do Composer. Para scripts localizados na pasta vendor/bin, não é necessário especificar esta pasta.

Como exemplo, definimos no arquivo composer.json um script que, usando o Nette Tester, executa os testes:

{
	"scripts": {
		"tester": "tester tests -s"
	}
}

Os testes são então executados usando composer tester. O comando pode ser chamado mesmo que não estejamos na pasta raiz do projeto, mas em algum subdiretório.

Envie agradecimentos

Mostraremos um truque que agradará os autores de open source. De maneira simples, você pode dar uma estrela no GitHub às bibliotecas que seu projeto usa. Basta instalar a biblioteca symfony/thanks:

composer global require symfony/thanks

E depois executar:

composer thanks

Experimente!

Configuração

O Composer está intimamente ligado à ferramenta de versionamento Git. Se você não o tiver instalado, é necessário dizer ao Composer para não usá-lo:

composer -g config preferred-install dist