# Statická analýza: PHPStan a Psalm

> PHPStan a Psalm vysvětleny: úrovně pravidel, baseline, taint analýza a co statická analýza může a nemůže přinést pro bezpečné aplikace v PHP.

Zdroj: https://phpsos.de/cs/php/statische-analyse/  
Stav: 25.10.2026  
Poskytovatel: PHP SOS, Nouzová pomoc pro PHP a bezpečnost serverů. Okamžitá pomoc přes WhatsApp: https://wa.me/491736494914?text=Dobr%C3%BD%20den%2C%20PHP%20SOS%2C%20pot%C5%99ebujeme%20pomoc%20s%20na%C5%A1%C3%ADm%20PHP%20serverem.%20Firma%3A%20%E2%80%A6%20Web%3A%20%E2%80%A6

**Stručně:** Statická analýza kontroluje kód PHP, aniž by jej spouštěla, a nachází tak chyby typů, nedefinované proměnné, mrtvý kód a volání na možná prázdných hodnotách. Dva rozšířené nástroje jsou PHPStan (úrovně pravidel 0 až 10) a Psalm (úrovně chyb 1 až 8, k tomu taint analýza nebezpečných toků dat). Najdou chyby ve vaší aplikaci, ne v interpretu PHP; proti zranitelnostem jako PHP2Shell pomáhá jen aktualizace PHP.

## Co je statická analýza?

Test spouští kód a porovnává výsledek. Statická analýza naproti tomu čte kód jako velmi důkladný kontrolor a z typů, návratových hodnot a volání vyvozuje, kde se může něco pokazit. Chyby najde i ve větvích, kterých žádný test nikdy nedosáhne.

Pro rozhodovatele je přínos jednoduchý: chyby nalezené před spuštěním naostro stojí zlomek toho, co chyby, kterých si všimnou zákazníci. Pro vývojáře je to stálý společník, který běží ve vývojovém prostředí i v CI pipeline. Pokud analýza u změny zasáhne, změna se nepřevezme, dokud se chyba neopraví. Nenarůstá tak nový starý dluh, zatímco stávající se postupně odbourává. Spolu s [testy pomocí PHPUnit a Pest](https://phpsos.de/cs/php/php-testen/) tvoří základ kvality kódu.

## PHPStan: úrovně pravidel od 0 do 10

PHPStan se instaluje jako vývojová závislost a ke svému běhu potřebuje PHP od 7.4:

```bash
composer require --dev phpstan/phpstan
vendor/bin/phpstan analyse src tests
```

Bez dalšího nastavení PHPStan kontroluje jen to nejnutnější. Přísnost řídíte jedenácti úrovněmi, každá zahrnuje ty pod ní:

| Úroveň | Co se navíc kontroluje (výběr) |
|---|---|
| 0 | neznámé třídy a funkce, špatný počet argumentů, vždy nedefinované proměnné |
| 3 | návratové typy a typy, které se přiřazují vlastnostem |
| 5 | typy argumentů při voláních funkcí a metod |
| 6 | chybějící údaje o typech |
| 8 | volání metod a přístupy k vlastnostem u hodnot, které mohou být null |
| 10 | nejpřísnější zacházení s `mixed`, i při chybějících typech |

S `--level max` běží vždy nejvyšší úroveň. Dokumentace však varuje, že upgrade PHPStan pak může přinést mnoho nových hlášení. Typický nález od úrovně 8:

```php
<?php
function kundenname(?Kunde $kunde): string
{
    return $kunde->name();   // PHPStan: volání na hodnotě, která může být null
}
```

## Zavedení PHPStan bez záplavy chyb: baseline

V rozrostlých projektech PHPStan na vysoké úrovni často hlásí stovky míst. Baseline problém řeší: uloží všechna stávající hlášení do souboru a PHPStan od té doby hlásí už jen nové chyby.

```bash
vendor/bin/phpstan analyse --level 6 src tests --generate-baseline
```

Vytvořený soubor `phpstan-baseline.neon` zahrnete do konfigurace:

```neon
includes:
    - phpstan-baseline.neon

parameters:
    level: 6
    paths:
        - src
        - tests
```

Starý stav tak zůstane viditelně zdokumentován, zatímco nový kód musí být od začátku čistý.

## Psalm a taint analýza

Psalm sleduje podobné cíle jako PHPStan. Úrovně běží obráceně: 1 je nejpřísnější, 8 nejmírnější, výchozí je 2. Psalm vyžaduje PHP od 8.2 a nastavuje se takto:

```bash
composer require --dev vimeo/psalm
./vendor/bin/psalm --init
./vendor/bin/psalm --taint-analysis
```

Taint analýza je pro bezpečnost obzvlášť zajímavá. „Taint“ znamená znečištění: Psalm označí data ze zdrojů, které útočník může ovládat, například `$_GET`, `$_POST`, `$_COOKIE`, `$_REQUEST` nebo `php://input`. Poté sleduje, zda tato data nedorazí nechráněná na nebezpečná místa, takzvané sinky: výstup pomocí `echo`, `include`, `header` nebo dotazy SQL. K vestavěným kategoriím patří mimo jiné `sql`, `html`, `shell`, `include`, `eval`, `ssrf` a `unserialize`.

```php
<?php
// Psalm hlásí tok z $_GET do výstupu HTML (kategorie html)
echo 'Hallo ' . $_GET['name'];

// Opraveno: výstup escapovat podle kontextu
echo 'Hallo ' . htmlspecialchars($_GET['name'] ?? '', ENT_QUOTES, 'UTF-8');
```

Dokumentace Psalm otevřeně uvádí meze: analýza předpokládá, že escapování probíhá správně. Jemné chyby, například chybějící uvozovky kolem atributu HTML, mohou přesto nechat mezery. Psalm proto doporučuje parametrizované dotazy pro SQL a šablony citlivé na kontext pro HTML. Výsledky lze vypsat ve formátu SARIF, kterému rozumí mimo jiné GitHub Code Scanning.

## Statická analýza a bezpečnost po PHP2Shell

Zde stojí za to poctivě vymezit hranice. PHP2Shell, tedy CVE-2026-109618 a CVE-2026-109619, sídlí v interpretu PHP. Žádný nástroj, který čte váš aplikační kód, tyto zranitelnosti nenajde a žádná změna kódu je neuzavře. To dokáže jen aktualizace na PHP 8.5.12, 8.4.27, 8.3.36 nebo 8.2.35.

Přesto statická analýza k bezpečnosti přispívá, a to na třech místech:

1. **Schopnost upgradu:** Najde kód, který na nových verzích PHP už nepoběží. Tím klesá překážka přechodu z 8.1 nebo 8.2 na podporovanou verzi.
2. **Vlastní zranitelnosti:** Taint analýza najde cesty pro [SQL injection](https://phpsos.de/cs/ratgeber/sql-injection-php/), cross-site scripting nebo vkládání souborů. Projekt PHP ve své bezpečnostní politice vysvětluje, že nekontrolované vstupy do funkcí jako `mysqli_query()` nejsou chybou PHP, ale leží v odpovědnosti aplikace.
3. **Odolnost:** Mnoho fatálních chyb vzniká voláním na null nebo špatnými typy. php.net v souvislosti s CVE-2026-109619 výslovně radí odstranit v aplikaci fatální chyby vyvolatelné zvenčí.

Statická analýza nenahrazuje [bezpečnostní code review](https://phpsos.de/cs/blog/sicherheits-code-review-php/) prováděné lidmi, činí je ale efektivnějším, protože rutinní chyby jsou předem vytříděny.

## Jak konkrétně pomáhá PHP SOS?

V rámci [bezpečnostního auditu a penetračního testu](https://phpsos.de/cs/leistungen/sicherheitsaudit-penetrationstest/) postupujeme takto:

- **Zavést nástroje:** PHPStan nebo Psalm s vhodnou úrovní a baseline, zapojené do vaší stávající pipeline.
- **Posoudit bezpečnostní nálezy:** Zkontrolujeme výsledky taint analýzy a oddělíme skutečná rizika od falešných poplachů.
- **Připravit upgrade:** Ukážeme, která místa blokují přechod na podporovanou verzi PHP.
- **Předat výsledky:** Obdržíte prioritizovaný seznam s konkrétními místy v kódu pro svůj tým nebo agenturu.


## Časté dotazy

**Jaký je rozdíl mezi PHPStan a Psalm?**  
Oba kontrolují typy a hledají chyby bez spuštění. PHPStan počítá své úrovně od 0 (volná) do 10 (přísná), Psalm od 8 (volná) do 1 (přísná). Psalm má vestavěnou taint analýzu pro bezpečnostní problémy.

**Mohu PHPStan zavést do starého projektu?**  
Ano. S baseline uloží PHPStan všechna stávající hlášení do souboru a poté hlásí už jen nové chyby. Tým tak začne bez záplavy chyb a postupně odbourává starý dluh.

**Najde statická analýza PHP2Shell?**  
Ne. PHP2Shell sídlí v interpretu PHP, ne ve vašem kódu. Proti tomu pomáhá jen aktualizace PHP. Statická analýza ale pomáhá připravit kód na nové verze PHP, takže aktualizace je možná rychleji.

**Jakou úroveň zvolit?**  
Pro začátek nízkou úroveň bez baseline nebo vyšší úroveň s baseline. Důležitější než číslo je, aby analýza běžela automaticky při každé změně a nové chyby nepropustila.

## Zdroje

- [PHPStan](https://phpstan.org/)
- [Psalm](https://psalm.dev/)
- [OWASP Cheat Sheet Series](https://cheatsheetseries.owasp.org/)
