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 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:
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
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.
vendor/bin/phpstan analyse --level 6 src tests --generate-baseline
Vytvořený soubor phpstan-baseline.neon zahrnete do konfigurace:
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:
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
// 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:
- 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.
- Vlastní zranitelnosti: Taint analýza najde cesty pro SQL injection, 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. - 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 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 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.