composer

O que é gerenciador de dependências?

Ao longo dos anos, houve uma grande evolução no desenvolvimento das aplicações. Algo muito comum há vinte anos, hoje é impraticável. No passado, quando era preciso, por exemplo, acessar um banco de dados, o desenvolvedor programava todos os aspectos desta conexão ou copiava (basicamente um copy-paste) de alguém que já implementou isso.

Esta dinâmica de “copiar-colar” o código, evoluiu para a “copia” de pacotes. No lugar de copiar o código fonte diretamente, o desenvolvedor passou a obter pacotes que continham os códigos que necessitava, como para o acesso ao banco. Esses pacotes eram adicionados manualmente no projeto que estivesse desenvolvendo.

O problema desde cenário é que se um pacote copiado fosse alterado, por qualquer motivo, o desenvolvedor precisaria repetir todo o procedimento de adição do pacote no projeto. Claro que também precisava ficar atento para saber se o pacote foi alterado ou não.

Com o tempo, os pacotes passaram a serem mais utilizados, o que tornou este gerenciamento manual impraticável. Vindo ao resgaste disso, surgiram os gerenciadores de pacotes, também chamados de gerenciador de dependências. Essas ferramentas realizam automaticamente os procedimentos que os desenvolvedores faziam manualmente. Delegando o gerenciamento dos pacotes de um projeto, o desenvolvedor pode focar no que é mais importante, o desenvolvimento da aplicação que está criando.

Npm - Gerenciador de pacotes para JavaScript
Curso de Npm - Gerenciador de pacotes para JavaScript
CONHEÇA O CURSO

Mas o meu projeto é pequeno, preciso de um gerenciador de dependência?

Durante a criação de uma aplicação, não importa qual seja o seu tamanho, pacotes são adicionados para agilizar o desenvolvimento, mantê-la coesa e evitar a “reinvenção da roda”. Porque criar algo do zero, se outro desenvolvedor já implementou o mesmo procedimento?

Mesmo havendo a possibilidade de adicionar um pacote manualmente, este também pode fazer uso de outro pacote. Neste cenário, trabalhando de maneira manual, mesmo requerendo apenas um pacote, o desenvolvedor precisará se preocupar com dois.

Entretanto, não há garantias que será apenas uma dependência. O segundo pacote pode necessitar de outros e assim por diante, gerindo um complexo grafo de dependências.

Logo vemos que o projeto possui muitas dependências, o que não é ruim, mas gerencia-las manualmente se torna complicado ou mesmo impossível:

É neste momento que os gerenciadores de dependências são imprescindíveis. Eles gerenciam todas as ações com relação as dependências do projeto: listagem, adição, remoção e atualização. Além de analisar o grafo de dependência e garantir que as dependências dos pacotes utilizados no projeto também sejam obtidas.

Principais gerenciadores de dependência

Atualmente qualquer plataforma de desenvolvimento que se preze possui uma ferramenta que permite a criação, compartilhamento e consumo de códigos entre os desenvolvedores.

Existem várias que se encontram neste quesito, entre as mais populações temos:

  • NPM: Para aplicações web e JavaScript;
  • Yarn: Para aplicações web e JavaScript;
  • Composer: Para aplicações PHP;
  • Maven: Para aplicações Java e Kotlin;
  • Gradle: Para aplicações Java, Groovy, Kotlin, Android, Scala e JavaScript;
  • NuGet: Para aplicações .NET;
  • Pip: Para aplicações Python;
  • Rubygem: Para aplicações Ruby;
  • Mix: Para aplicações Elixir;
  • Hex: Para aplicações Erlang;
  • Cargo: Para aplicações Rust;
  • PEAR Installer: Para aplicações PHP;
  • CPAN: Para aplicações Pear.

Cada gerenciador de dependências possui suas particularidades, mas todos facilitam a vida do desenvolvedor, então saber utilizá-los é algo essencial atualmente. Aqui no nosso blog, já abordamos o Yarn, PIP, NPM e NuGet.

Composer - Gerenciador de dependências para PHP
Curso de Composer - Gerenciador de dependências para PHP
CONHEÇA O CURSO

Devemos abordar os outros gerenciadores em artigos futuros, então fique de olho nas nossas publicações aqui do blog.

Ferramentas essenciais para um projeto PHP

Este será um artigo um pouco diferente dos últimos que tenho escrito, vou citar as quatro principais ferramentas que considero essenciais para qualquer projeto PHP:

  • PHPUnit (Testes unitários);
  • PHPStan (Analisador estático);
  • PHP-CS-Fixer (Corrige estilo de código);
  • PHP Insights (Analisa o estilo e a qualidade do código);
Desenvolvedor PHP Sênior
Formação: Desenvolvedor PHP Sênior
Nesta formação você aprenderá aspectos avançados da linguagem PHP e de seu ecossistema, conhecimentos essenciais para se tornar um desenvolvedor diferenciado, e com isso, você terá conhecimento para desenvolver aplicações PHP usando as práticas mais modernas do mercado.
CONHEÇA A FORMAÇÃO

1) PHPUnit

O PHPUnit é o principal e mais estabelecido framework para testes unitários em PHP. Automatizar testes é um requisito cada vez mais essencial para os projetos, não importando se você vai seguir TDD como metodologia, mas pelo menos testar as partes mais críticas da aplicação é algo que pode te salvar algumas boas horas procurando bugs e corrigindo problemas da evolução natural do software.

Você pode instalá-lo em seu projeto executando:

$ composer require phpunit/phpunit:^8.0 --dev

Hoje a ferramenta já tem a documentação traduzida para o português, você pode ler aqui.

Testar no PHPUnit é super simples e bem parecido com a forma que se faz em outros frameworks de teste de outras linguagens:

Exemplo extraído da documentação:

<?php

declare(strict_types=1);

final class Email
{
    private $email;

    private function __construct(string $email)
    {
        $this->ensureIsValidEmail($email);

        $this->email = $email;
    }

    public static function fromString(string $email): self
    {
        return new self($email);
    }

    public function __toString(): string
    {
        return $this->email;
    }

    private function ensureIsValidEmail(string $email): void
    {
        if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            throw new InvalidArgumentException(
                sprintf(
                    '"%s" is not a valid email address',
                    $email
                )
            );
        }
    }
}

Essa classe poder ser facilmente testada:

<?php

declare(strict_types=1);

use PHPUnit\Framework\TestCase;

final class EmailTest extends TestCase
{
    public function testCanBeCreatedFromValidEmailAddress(): void
    {
        $this->assertInstanceOf(
            Email::class,
            Email::fromString('user@example.com')
        );
    }

    public function testCannotBeCreatedFromInvalidEmailAddress(): void
    {
        $this->expectException(InvalidArgumentException::class);

        Email::fromString('invalid');
    }

    public function testCanBeUsedAsString(): void
    {
        $this->assertEquals(
            'user@example.com',
            Email::fromString('user@example.com')
        );
    }
}
PHP - Testes unitários com PHPUnit
Curso de PHP - Testes unitários com PHPUnit
CONHEÇA O CURSO

2) PHPStan

O PHPStan é um analisador estático que varre o código da sua aplicação procurando por erros e incongruências sem que haja a necessidade de executá-lo, a análise é toda estática.

É uma ferramenta essencial para te apontar bugs ou erros que certamente aparecerão em algum momento do uso da aplicação.

Para instalar o PHPStan no seu projeto:

$ composer require --dev phpstan/phpstan

Uma vez instalado, basta executar a ferramenta indicando quais pastas ele deve avaliar:

$ ./vendor/bin/phpstan analyse src tests

Nesse caso, estará avaliando as pastas src e tests.

Você ainda pode especificar o quão estrita você quer que a análise seja feita. Por padrão ele opera no level 0, mas vai até o 7:

$ ./vendor/bin/phpstan analyse src tests --level 7

Para aplicações que rodam em cima do Laravel, tem o Larastan, que facilita a instalação e personalização.

Apesar de eu preferir o PHPStan, também existe o ótimo Psalm, mantido pelo pessoal do Vimeo. Vale a pena estudá-lo, talvez você venha a preferi-lo.

3) PHP-CS-Fixer

O PHP-CS-Fixer corrige todo o estilo do seu código, quebras, espaços, estilo de declarações etc. É possível definir para que ele siga as PSR-1 e PSR-2, por exemplo. Não obstante, já estão desenvolvendo suporte nele para o mais novo padrão de estilo de código, o PSR-12.

Para instalá-lo em seu projeto:

$ composer require friendsofphp/php-cs-fixer --dev

E para rodar as correções usando as regras da PSR-2:

./vendor/bin/php-cs-fixer fix src --rules=@PSR2 --allow-risky yes

Nesse caso ele rodará na pasta src.

Uma forma mais simples de configurar o perfil de execução dele é criando um arquivo .php_cs na raiz do seu projeto e então definir o que é pra ele validar, o que não é, quais regras usar, quais configurações de estilo usar etc. Em nossas aplicações no TreinaWeb usamos esse perfil:

<?php

$finder = Symfony\Component\Finder\Finder::create()
    ->notPath('vendor')
    ->notPath('bootstrap')
    ->notPath('storage')
    ->notPath('resources')
    ->in(__DIR__)
    ->name('*.php')
    ->notName('*.blade.php');

return PhpCsFixer\Config::create()
    ->setRules([
        '@PSR2' => true,
        'final_class' => true,
        'static_lambda' => true,
        'linebreak_after_opening_tag' => true,
        'blank_line_after_opening_tag' => true,
        'declare_strict_types' => true,
        'array_syntax' => ['syntax' => 'short'],
        'ordered_imports' => ['sortAlgorithm' => 'length'],
        'no_unused_imports' => true,
        'native_function_invocation' => true,
        'is_null' => true,
        'list_syntax' => [
            'syntax' => 'short',
        ],
        'lowercase_cast' => true,
        'lowercase_static_reference' => true,
        'mb_str_functions' => true,
        'modernize_types_casting' => true,
        'native_constant_invocation' => true,
        'native_function_casing' => true,
        'new_with_braces' => true,
        'blank_line_before_statement' => [
            'statements' => ['declare',],
        ],
        'return_type_declaration' => [
            'space_before' => 'none',
        ],
    ])
    ->setFinder($finder);

Outras configurações você pode verificar no repositório oficial da ferramenta. Uma vez tendo o arquivo .php_cs, é só executar sem precisar informar --rules:

./vendor/bin/php-cs-fixer fix src --allow-risky yes

4) PHP Insights

Ferramenta para análise da qualidade do código. Ele divide a análise em quatro categorias: código, complexidade (complexidade ciclomática etc), arquitetura (tamanho de métodos e classes, entre outras análises) e estilo de código (formatação, padronização).

Para instalar a ferramenta no seu projeto:

$ composer require nunomaduro/phpinsights --dev

Depois, basta executar:

$ ./vendor/bin/phpinsights

Você pode criar um arquivo phpinsights.php na raiz do seu projeto para configurar o perfil da análise, ou seja, para definir o que você quer remover da análise, o que quer incluir etc. Por exemplo:

<?php

declare(strict_types=1);

use ObjectCalisthenics\Sniffs\Files\FunctionLengthSniff;
use NunoMaduro\PhpInsights\Domain\Insights\ForbiddenTraits;
use ObjectCalisthenics\Sniffs\Metrics\MethodPerClassLimitSniff;
use SlevomatCodingStandard\Sniffs\TypeHints\TypeHintDeclarationSniff;
use NunoMaduro\PhpInsights\Domain\Insights\CyclomaticComplexityIsHigh;
use SlevomatCodingStandard\Sniffs\TypeHints\DisallowMixedTypeHintSniff;
use NunoMaduro\PhpInsights\Domain\Insights\Composer\ComposerMustBeValid;
use SlevomatCodingStandard\Sniffs\Namespaces\AlphabeticallySortedUsesSniff;
use PHP_CodeSniffer\Standards\PSR1\Sniffs\Methods\CamelCapsMethodNameSniff;
use PHP_CodeSniffer\Standards\Generic\Sniffs\Files\LineLengthSniff;

return [
    'preset' => 'default',

    'exclude' => [
        'vendor',
        'config',
        'bootstrap',
        'resources',
        'storage',
        'public',
        'tests',
    ],

    'add' => [

    ],

    'remove' => [
        ForbiddenTraits::class,
        TypeHintDeclarationSniff::class,
        DisallowMixedTypeHintSniff::class,
        ComposerMustBeValid::class,
        AlphabeticallySortedUsesSniff::class,
        CamelCapsMethodNameSniff::class,
        LineLengthSniff::class,
    ],

    'config' => [
        CyclomaticComplexityIsHigh::class => [
            'maxComplexity' => 7,
        ],

        FunctionLengthSniff::class => [
            'maxLength' => 30,
        ],

        MethodPerClassLimitSniff::class => [
            'maxCount' => 12,
        ],
    ],
];

Maiores informações sobre a configuração da ferramenta, você pode ver no site oficial.

Usando o Composer como atalho para a execução de scripts

Por fim, uma coisa que acho bem útil e que uso bastante é colocar no composer.json atalhos para os scripts de linha de comando que mais executo no projeto. É possível defini-los numa área scripts, por exemplo:

    "scripts": {
        "phpunit": [
            "./vendor/bin/phpunit"
        ],        
        "cs": [
            "./vendor/bin/php-cs-fixer fix --allow-risky yes"
        ],
        "phpstan": [
            "./vendor/bin/phpstan analyse src tests --level 7"
        ],
        "phpinsights": [
            "./vendor/bin/phpinsights"
        ]
    },

Então, ao invés de executar ./vendor/bin/phpstan analyse src tests --level 7 eu apenas faço:

$ composer phpstan

O mesmo vale para a correção do estilo do código, apenas executo:

$ composer cs

Concluindo

Espero que o artigo tenha despertado a sua curiosidade. Recomendo demais que você leia a documentação dessas ferramentas e passe a utilizá-las, em pouco tempo você estará “viciado” e certamente as usará em todos os futuros projetos.

Até a próxima!

O que é o Symfony Flex e como ele funciona

O Symfony é um dos frameworks mais utilizados na linguagem PHP. Ele possui grande importância no ecossistema, pois além da utilização direta do framework, diversas outras ferramentas e até frameworks utilizam seus componentes como base de desenvolvimento. Mesmo com tanta relevância o Symfony não era tão falado na comunidade brasileira, porém com as novidades apresentadas nos últimos tempos ele voltou a ganhar bastante destaque. Inclusive, prova disso é o evento oficial da Symfony que aconteceu em São Paulo.

Um dos recursos mais interessantes apresentados pela equipe do Symfony é o Flex. Ele automatiza o processo de configuração das dependências no momento da instalação. Isso possibilita ao desenvolvedor começar o projeto com o mínimo possível de dependencias, algo parecido com um micro framework, e adicionar novas dependencias de forma muito fluida até chegar a uma estrutura parecida com um framework full stack.

Symfony - Gerenciando aplicações com Symfony Flex
Curso de Symfony - Gerenciando aplicações com Symfony Flex
CONHEÇA O CURSO

O que é Symfony Flex

O Symfony Flex é um plugin para composer. Ele automatiza os principais processos na hora da criação do projeto e instalação das dependências. Pode ser usado a partir da versão 3.4 do Symfony e passou a ser usado por padrão a partir da versão 4. O Flex altera o comportamento padrão de alguns dos comandos do Composer para permitir a automatização das tarefas de gerenciamento do projeto.

Quando realizamos a instalação de um novo pacote do composer, o Symfony Flex verifica dentro de um repositório próprio se existe alguma automatização correspondente a essa dependência, se existir ele executa as ações definidas.

O que são Recipes

Recipe (receita) é o nome dado ao conjunto de arquivos responsável pela automatização do processo de instalação de uma dependência específica. As instruções são definidas dentro de um arquivo chamado manifest.json que fica dentro do repositório do Flex, veja um exemplo abaixo:

{
    "bundles": {
        "Symfony\Bundle\DebugBundle\DebugBundle": ["dev", "test"]
    },
    "copy-from-recipe": {
        "config/": "%CONFIG_DIR%/"
    }
}

O recipe acima está pedindo para adicionar um novo bundle no arquivo de configuração e copiar a pasta config de dentro do repositório do Symfony Flex para o projeto. Esse arquivo faz parte do recipe de debug https://github.com/symfony/recipes/blob/master/symfony/debug-bundle/4.1/manifest.json

Ao executar essas tarefas, o Flex evita que o desenvolvedor necessite executar manualmente, diminuindo a chance de erro e a complexidade de instalação de novos pacotes.

Repositório de recipes

O Symfony Flex possui 2 repositórios de recipes. O primeiro é o repositório oficial onde somente projetos da equipe do Symfony são colocados:

repositorio github symfony recipes

O segundo é o repositório contrib onde qualquer pessoa pode submeter um recipe para automatizar as configurações do seu bundle.

repositorio contrib symfony

Ainda é possível criar repositórios privados onde podemos colocar as recipes do Flex que serão usadas somente dentro dos nossos projetos.

Como o Flex cria a estrutura da aplicação Symfony na instalação

Symfony - Fundamentos
Curso de Symfony - Fundamentos
CONHEÇA O CURSO

Como instalar novas dependências no projeto

Uma vez que temos uma aplicação que utiliza o Flex podemos facilmente instalar novas dependências e se beneficiar das automatizações. O Symfony possui uma página onde podemos consultar todos os recipes tanto oficiais quanto do repositório de contrib https://flex.symfony.com, vamos procurar por twig:

busca de recipes

Note que temos vários recipes relacionados ao twig. Vamos instalar o pacote symfony/twig-bundle.

composer require symfony/twig-bundle

Se tudo der certo o resultado final será parecido com esse:

terminal com resultado pacote symfony

Note que após instalar o pacote do composer no projeto ele executou o recipe. Ao fazer isso o Flex configurou todos os detalhes necessários para o Twig funcionar no seu projeto. Podemos ver isso na prática se olharmos no Git as alterações realizadas:

alterações git realizadas

Apelidos para os pacotes do Flex

Alguns pacotes possuem Aliases (apelidos). Se notar o pacote que instalamos verá que ele possui alguns nomes definidos:

alias de recipe symfony

O principal objetivo do alias é facilitar na hora de instalação, podemos fazer simplesmente:

composer require twig

Ou

composer require template

Se estiver dentro de uma aplicação que não utiliza o Flex, o composer não vai encontrar esses pacotes, pois o padrão para identificação de pacotes do composer é nome-vendor/nome-pacote. Usar apelidos só é possível graças ao Symfony Flex e em pacotes que possuem Recipes.

Symfony -  Formulários e Validações
Curso de Symfony - Formulários e Validações
CONHEÇA O CURSO

Prefetch e download simultâneo

Quando usamos o Flex ele adiciona 2 funções muito interessantes ao composer:

  • Prefetch – Ele baixa todos os pacotes necessários antes de iniciar a instalação
  • Download Simultâneo – O composer por padrão baixa uma dependência por vez, com uso do Flex ele passar a realizar o download ao mesmo tempo de vários pacotes, tornando mais rápido o processo.

O interessante é que se instalarmos o Flex globalmente no sistema operacional esses 2 recursos passam a ser usados em qualquer projeto, mesmo que não utilize o Symfony. Para instalar o Flex global basta executar:

composer global require symfony/flex 

Conclusão

O Flex torna o gerenciamento das dependências de uma aplicação muito mais simples, rápido e seguro. Uma vez que remove a necessidade de configuração manual por parte do desenvolvedor. Além disso ele ainda conta com uma série de recursos avançados que facilitam o trabalho diário de manutenção de aplicações Symfony.

Caso queira aprofundar seus conhecimentos abordamos o assunto em diversas ocasiões utilizando o Symfony aqui no blog, confira!

Desenvolvedor Symfony Full-Stack
Formação: Desenvolvedor Symfony Full-Stack
Nesta formação você aprenderá desenvolver aplicações PHP usando o framework Symfony com desenvoltura. Ao final desta formação, terá condições de trabalhar em grandes aplicações web ou APIs integradas com diversos serviços, tudo isso usando as melhores práticas do mercado.
CONHEÇA A FORMAÇÃO

© 2004 - 2019 TreinaWeb Tecnologia LTDA - CNPJ: 06.156.637/0001-58 Av. Paulista, 1765, Conj 71 e 72 - Bela Vista - São Paulo - SP - 01311-200