Ferramentas de análise estática: PHPStan e Psalm

1. Introdução à análise estática em PHP

Análise estática é o processo de examinar o código-fonte sem executá-lo, identificando possíveis erros, inconsistências de tipos e más práticas antes mesmo que o software entre em produção. Diferente dos testes unitários e de integração — que verificam comportamentos esperados em tempo de execução — a análise estática atua como uma camada preventiva, capturando problemas estruturais que poderiam passar despercebidos.

Para projetos PHP, onde a tipagem dinâmica sempre foi uma faca de dois gumes, ferramentas como PHPStan e Psalm tornaram-se indispensáveis. Elas detectam chamadas a métodos inexistentes, retornos inconsistentes, variáveis não inicializadas e até vulnerabilidades de segurança. O resultado é um código mais previsível, manutenível e com custos reduzidos de correção tardia.

2. PHPStan: o guardião dos tipos

PHPStan é uma ferramenta de análise estática focada em tipos, criada por Ondřej Mirtes. Sua instalação via Composer é simples:

composer require --dev phpstan/phpstan

A configuração básica é feita em um arquivo phpstan.neon:

parameters:
    level: 5
    paths:
        - src

O grande diferencial do PHPStan são seus níveis de rigor, que vão do 0 (básico) ao 9 (máximo). Cada nível adiciona novas verificações. Exemplo prático de detecção:

<?php
// Exemplo que PHPStan nível 5 detecta
class Usuario {
    public function getNome(): string {
        return "João";
    }
}

$usuario = new Usuario();
echo $usuario->getNome(); // OK

$usuario->getIdade(); // Erro: método inexistente

Com PHPStan nível 5, o comando vendor/bin/phpstan analyse apontará o erro Call to an undefined method Usuario::getIdade(). Em níveis mais altos, ele também rejeitaria retornos inconsistentes:

<?php
function processar(int $valor): string {
    if ($valor > 10) {
        return "grande";
    }
    // Nível 6+ detecta: missing return statement
}

3. Psalm: o profeta da integridade do código

Psalm, mantido pelo Vimeo, é outra ferramenta poderosa que vai além da análise de tipos. Instalação:

composer require --dev vimeo/psalm

Configuração via psalm.xml:

<?xml version="1.0"?>
<psalm
    errorLevel="3"
    resolveFromConfigFile="true"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="https://getpsalm.org/schema/config"
    xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
>
    <projectFiles>
        <directory name="src" />
    </projectFiles>
</psalm>

Psalm oferece modos especiais, como análise de taint (fluxo de dados sensíveis). Exemplo:

<?php
function buscarUsuario(string $id): array {
    $sql = "SELECT * FROM usuarios WHERE id = $id"; // Taint: SQL injection
    return [];
}

$id = $_GET['id']; // Fonte de dados não confiável
$usuario = buscarUsuario($id);

Psalm com modo --taint-analysis detectaria esse vazamento de dados sensíveis. Outro exemplo comum:

<?php
function saudacao(string $nome): string {
    if ($nome === '') {
        return "Olá, visitante!";
    }
    // Psalm modo estrito detecta: variável $saudacao não inicializada
    $saudacao = "Olá, $nome!";
    return $saudacao;
}

4. Comparação entre PHPStan e Psalm

Ambas as ferramentas seguem padrões PSR, suportam anotações PHPDoc e oferecem plugins. As diferenças principais:

Característica PHPStan Psalm
Abordagem Bottom-up (análise local) Top-down (análise de fluxo)
Taint analysis Não nativo Nativo
Performance Rápido em projetos grandes Levemente mais lento
Níveis de rigor 0-9 1-8 (invertido: 1 é mais rigoroso)

Para escolher: PHPStan é ideal para projetos legados que precisam de adoção gradual (níveis baixos). Psalm é superior quando segurança é prioridade, graças à análise de taint embutida.

5. Integração com fluxos de trabalho modernos

Ambas as ferramentas se integram perfeitamente a pipelines CI/CD. Exemplo com GitHub Actions:

name: Static Analysis
on: [push]
jobs:
  phpstan:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: shivammathur/setup-php@v2
        with:
          php-version: '8.2'
      - run: composer install
      - run: vendor/bin/phpstan analyse --error-format=github

Em IDEs, extensões como "PHPStan" para VS Code ou o suporte nativo do PhpStorm permitem ver erros em tempo real. A combinação com PHP-CS-Fixer (formatação) e PHPUnit (testes) cria um ecossistema de qualidade completo.

6. Plugins e extensões essenciais

Plugins estendem a análise para frameworks específicos:

  • PHPStan Laravel (phpstan/phpstan-laravel): detecta métodos mágicos do Eloquent
  • Psalm Symfony (psalm/psalm-symfony): analisa injeção de dependência
  • PHPStan Doctrine (phpstan/phpstan-doctrine): valida consultas DQL

Para código legado, extensões como phpstan/phpstan-deprecation-rules ajudam na migração gradual. É possível criar regras personalizadas:

<?php
// Exemplo de regra personalizada PHPStan
class NomesDeMetodosComPrefixoRule implements \PHPStan\Rules\Rule
{
    public function getNodeType(): string
    {
        return \PhpParser\Node\Expr\MethodCall::class;
    }

    public function processNode(\PhpParser\Node $node, \PHPStan\Analyser\Scope $scope): array
    {
        if ($node->name->name === 'executar') {
            return ['Método "executar" não permitido. Use "processar".'];
        }
        return [];
    }
}

7. Boas práticas e adoção em times

A adoção gradual é a chave para o sucesso. Comece com nível baixo (PHPStan nível 0 ou Psalm nível 8) e aumente conforme a equipe se adapta. Documente as regras em um arquivo de configuração compartilhado e realize sessões de treinamento.

Para mitigar falsos positivos, use anotações @phpstan-ignore ou configure exceções no arquivo de configuração:

<?php
/** @phpstan-ignore-next-line */
$resultado = metodoNaoAnalisado();

Estabeleça um processo: todo pull request deve passar pela análise estática antes do merge. Ferramentas como phpstan-baseline geram um arquivo de erros conhecidos, permitindo focar em novos problemas.

8. Conclusão e próximos passos

PHPStan e Psalm transformaram a forma como desenvolvemos em PHP. Elas trazem segurança de tipos, detecção precoce de bugs e redução drástica de custos de manutenção. Um código analisado estaticamente é mais previsível, seguro e fácil de refatorar.

O futuro aponta para integração com inteligência artificial (como sugestões automáticas de correção) e suporte cada vez mais robusto aos recursos modernos do PHP 8.x (enums, readonly properties, union types). Invista tempo nessas ferramentas hoje — sua base de código agradecerá amanhã.

Referências