# Análise estática: PHPStan e Psalm

> PHPStan e Psalm explicados: níveis de regras, baseline, análise de taint e o que a análise estática pode e não pode fazer por aplicações PHP seguras.

Fonte: https://phpsos.de/pt/php/statische-analyse/  
Atualizado em: 25/10/2026  
Prestador: PHP SOS, Assistência de emergência PHP e segurança de servidores. Ajuda imediata por WhatsApp: https://wa.me/491736494914?text=Ol%C3%A1%2C%20PHP%20SOS%2C%20precisamos%20de%20ajuda%20com%20o%20nosso%20servidor%20PHP.%20Empresa%3A%20%E2%80%A6%20Site%3A%20%E2%80%A6

**Em resumo:** A análise estática verifica o código PHP sem o executar e encontra assim erros de tipo, variáveis indefinidas, código morto e chamadas sobre valores possivelmente vazios. As duas ferramentas mais difundidas são o PHPStan (níveis de regras de 0 a 10) e o Psalm (níveis de erro de 1 a 8, mais uma análise de taint para fluxos de dados inseguros). Encontram erros na sua aplicação, não no interpretador PHP; contra vulnerabilidades como o PHP2Shell só ajuda a atualização do PHP.

## O que é a análise estática?

Um teste executa o código e compara o resultado. A análise estática, em contrapartida, lê o código como um revisor muito minucioso e deduz, a partir de tipos, valores de retorno e chamadas, onde algo pode correr mal. Encontra erros mesmo em ramos que nenhum teste alguma vez alcança.

Para quem decide, o benefício é simples: os erros encontrados antes da entrada em produção custam uma fração dos que os clientes notam. Para os programadores, é uma companheira constante, que corre no ambiente de desenvolvimento e na pipeline de CI. Se a análise disparar numa alteração, esta não é aceite até o erro ser corrigido. Assim não se acumula novo legado, enquanto o existente vai sendo eliminado por etapas. Em conjunto com os [testes com PHPUnit e Pest](https://phpsos.de/pt/php/php-testen/), forma a base da qualidade do código.

## PHPStan: níveis de regras de 0 a 10

O PHPStan instala-se como dependência de desenvolvimento e precisa, para correr, do PHP a partir da versão 7.4:

```bash
composer require --dev phpstan/phpstan
vendor/bin/phpstan analyse src tests
```

Sem mais indicações, o PHPStan verifica apenas o essencial. O rigor controla-se através de onze níveis, cada um incluindo os inferiores:

| Nível | O que se verifica adicionalmente (seleção) |
|---|---|
| 0 | classes e funções desconhecidas, número errado de argumentos, variáveis sempre indefinidas |
| 3 | tipos de retorno e tipos atribuídos a propriedades |
| 5 | tipos dos argumentos em chamadas de funções e métodos |
| 6 | indicações de tipo em falta |
| 8 | chamadas de métodos e acessos a propriedades em valores que podem ser nulos |
| 10 | tratamento mais rigoroso de `mixed`, também com tipos em falta |

Com `--level max` corre sempre o nível mais alto. A documentação adverte, porém, que uma atualização do PHPStan pode então trazer muitas mensagens novas. Um achado típico a partir do nível 8:

```php
<?php
function kundenname(?Kunde $kunde): string
{
    return $kunde->name();   // PHPStan: chamada sobre um valor que pode ser nulo
}
```

## Introduzir o PHPStan sem enxurrada de erros: a baseline

Em projetos crescidos organicamente, o PHPStan comunica muitas vezes centenas de pontos num nível alto. A baseline resolve o problema: guarda todas as mensagens existentes num ficheiro, e o PHPStan passa a comunicar apenas erros novos.

```bash
vendor/bin/phpstan analyse --level 6 src tests --generate-baseline
```

O ficheiro gerado `phpstan-baseline.neon` é incluído na configuração:

```neon
includes:
    - phpstan-baseline.neon

parameters:
    level: 6
    paths:
        - src
        - tests
```

Assim, o legado fica documentado de forma visível, enquanto o código novo tem de estar limpo desde o início.

## Psalm e a análise de taint

O Psalm persegue objetivos semelhantes aos do PHPStan. Os níveis correm ao contrário: 1 é o mais rigoroso, 8 o mais indulgente, a predefinição é 2. O Psalm precisa do PHP a partir da versão 8.2 e configura-se assim:

```bash
composer require --dev vimeo/psalm
./vendor/bin/psalm --init
./vendor/bin/psalm --taint-analysis
```

A análise de taint é particularmente interessante para a segurança. «Taint» significa contaminação: o Psalm marca os dados vindos de fontes que um atacante pode controlar, como `$_GET`, `$_POST`, `$_COOKIE`, `$_REQUEST` ou `php://input`. Depois segue se esses dados chegam sem proteção a pontos perigosos, os chamados sinks: saída com `echo`, `include`, `header` ou consultas SQL. Entre as categorias integradas contam-se, entre outras, `sql`, `html`, `shell`, `include`, `eval`, `ssrf` e `unserialize`.

```php
<?php
// O Psalm assinala um fluxo de $_GET para a saída HTML (categoria html)
echo 'Hallo ' . $_GET['name'];

// Corrigido: escapar a saída de acordo com o contexto
echo 'Hallo ' . htmlspecialchars($_GET['name'] ?? '', ENT_QUOTES, 'UTF-8');
```

A documentação do Psalm indica abertamente os limites: a análise assume que o escape é feito corretamente. Erros subtis, como a falta de aspas à volta de um atributo HTML, podem ainda assim deixar falhas. O Psalm recomenda por isso consultas parametrizadas para SQL e templates sensíveis ao contexto para HTML. Os resultados podem ser emitidos no formato SARIF, que o GitHub Code Scanning, entre outros, compreende.

## Análise estática e segurança após o PHP2Shell

Aqui compensa uma delimitação honesta. O PHP2Shell, ou seja, a CVE-2026-109618 e a CVE-2026-109619, está no interpretador PHP. Nenhuma ferramenta que leia o código da sua aplicação encontra estas vulnerabilidades, e nenhuma alteração de código as fecha. Isso só o faz a atualização para o PHP 8.5.12, 8.4.27, 8.3.36 ou 8.2.35.

Ainda assim, a análise estática contribui para a segurança em três pontos:

1. **Capacidade de atualização:** encontra código que já não corre em versões novas do PHP. Isso baixa a barreira para passar do 8.1 ou 8.2 a uma versão suportada.
2. **Vulnerabilidades próprias:** a análise de taint encontra caminhos para [SQL injection](https://phpsos.de/pt/ratgeber/sql-injection-php/), cross-site scripting ou inclusão de ficheiros. O projeto PHP esclarece na sua política de segurança que entradas não verificadas passadas a funções como `mysqli_query()` não são um erro do PHP, mas responsabilidade da aplicação.
3. **Robustez:** muitos erros fatais surgem de chamadas sobre null ou de tipos errados. Em relação à CVE-2026-109619, o php.net aconselha expressamente corrigir na aplicação os erros fatais que podem ser desencadeados do exterior.

A análise estática não substitui uma [revisão de código de segurança](https://phpsos.de/pt/blog/sicherheits-code-review-php/) feita por pessoas, mas torna-a mais eficiente, porque os erros de rotina já foram triados antes.

## Como ajuda concretamente a PHP SOS?

No âmbito da [auditoria de segurança e teste de intrusão](https://phpsos.de/pt/leistungen/sicherheitsaudit-penetrationstest/), procedemos assim:

- **Configurar as ferramentas:** PHPStan ou Psalm com o nível adequado e baseline, integrados na sua pipeline existente.
- **Avaliar os achados de segurança:** verificamos os resultados da análise de taint e separamos os riscos reais dos falsos alarmes.
- **Preparar a atualização:** mostramos que pontos bloqueiam a mudança para uma versão do PHP suportada.
- **Entregar os resultados:** recebe uma lista priorizada, com pontos concretos do código, para a sua equipa ou agência.


## Perguntas frequentes

**Qual é a diferença entre o PHPStan e o Psalm?**  
Ambos verificam tipos e encontram erros sem execução. O PHPStan conta os seus níveis de 0 (laxo) a 10 (rigoroso), o Psalm de 8 (laxo) a 1 (rigoroso). O Psalm traz uma análise de taint integrada para problemas de segurança.

**Posso introduzir o PHPStan num projeto antigo?**  
Sim. Com uma baseline, o PHPStan guarda todas as mensagens existentes num ficheiro e depois só comunica erros novos. Assim a equipa arranca sem uma enxurrada de erros e vai eliminando o legado por etapas.

**A análise estática encontra o PHP2Shell?**  
Não. O PHP2Shell está no interpretador PHP, não no seu código. Contra ele só ajuda a atualização do PHP. A análise estática ajuda, porém, a preparar o código para novas versões do PHP, para que a atualização seja possível mais depressa.

**Que nível se deve escolher?**  
Para começar, um nível baixo sem baseline ou um nível mais alto com baseline. Mais importante do que o número é que a análise corra automaticamente a cada alteração e não deixe passar erros novos.

## Fontes

- [PHPStan](https://phpstan.org/)
- [Psalm](https://psalm.dev/)
- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
