Slovník pojmů
Statická analýza kódu: chyby, které lze najít před spuštěním
Nástroje jako PHPStan a Psalm doplňují testy rychlou kontrolou typů a možných chyb napříč kódem.
Stručná definice
Kontrola zdrojových souborů bez spuštění aplikace.
Analyzátor vychází z deklarací typů, signatur metod, PHPDoc, dostupných tříd a možných cest v programu. Dokáže upozornit například na volání metody na hodnotě, která může být null, nesprávný typ argumentu, chybějící metodu nebo část nedosažitelného kódu.
Neověřuje však, zda obchodní pravidlo odpovídá zadání ani zda externí API skutečně odpoví správně. Statická analýza není náhradou testů, monitoringu nebo code review; hledá jiný typ rizika a právě proto se s nimi dobře doplňuje.
Použití
K čemu se analýza používá
Je zvlášť užitečná při údržbě a refaktoringu systému s mnoha rozhraními a datovými zdroji.
- typy argumentů, návratových hodnot, vlastností a kolekcí
- neexistující třídy, metody, vlastnosti a neplatná volání
- nullable hodnoty bez předchozí kontroly
- přesnější kontrakty DTO, repository a generických pomocných tříd
- kontrola změn v pull requestu před mergem do hlavní větve
Praktický příklad
Chybějící zákazník při importu
Repository může vracet ?Customer, protože pro dané externí ID zákazník neexistuje. Pokud import bez kontroly pokračuje a čte jeho e-mail, analyzátor na vyšší úrovni upozorní na volání metody nad hodnotou, která může být null.
Správná oprava není umlčet hlášení. Aplikace musí vyjádřit zamýšlené chování: zákazníka vytvořit, import označit za neúplný, nebo použít metodu, jejíž kontrakt při nenalezení vyhodí konkrétní výjimku. Analýza nevymýšlí business rozhodnutí, ale nutí ho udělat viditelným.
Jak funguje
Od typové informace k diagnostice
Přesnost stojí na tom, jak dobře projekt popisuje své skutečné kontrakty.
- Vstup PHP soubory, Composer autoloading, nativní typy, PHPDoc a konfigurace frameworku.
- Model Nástroj sestaví známé třídy, metody, vlastnosti a možné typy hodnot.
- Průchod kódem Vyhodnocuje možné větve a ověřuje, zda jsou operace nad danými typy bezpečné.
- Diagnostika Výsledek ukáže soubor, řádek a důvod rozporného kontraktu.
- CI gate Při nové chybě může kontrola zastavit pull request nebo merge.
Co je co
Statická analýza není jen lint
Týmy používají slovo lint různě, proto je dobré pojmenovat konkrétní druh kontroly.
Syntax lint
php -l ověří, zda parser dokáže soubor načíst. Nenajde ale volání $customer->email() ve chvíli, kdy customer může být null.
Code style a architektura
ECS nebo PHP_CodeSniffer hlídají zápis, importy a týmové konvence. Pomáhají čitelnosti, ale neprokazují správné typy. Deptrac pak kontroluje povolené závislosti mezi vrstvami, nikoli typy jednotlivých výrazů.
Automatizované testy
Testy aplikaci spouštějí v konkrétních scénářích a ověřují pravidla či integrace. Analýza je rychlejší a projde i nevolané větve.
PHPStan a Psalm
Jde o samostatné analyzátory s vlastní konfigurací a rozšířeními. Není nutné provozovat oba; důležitější je důvěryhodná typová informace a průběžné řešení nálezů.
Přísnost a typy
Nativní typy, PHPDoc, generika a baseline
Vyšší přísnost není cíl sama o sobě. Má zlepšovat spolehlivost kontraktů, ne jen měnit číslo v konfiguraci.
- Nativní typy
- Typy parametrů, návratů a vlastností jsou základ, který běží i za provozu.
- PHPDoc a generika
- Doplňují informace, které PHP neumí vyjádřit přesně, například typ prvků kolekce nebo @template T. Oprava má vznikat u zdroje hodnoty.
- Úrovně pravidel
- PHPStanovy vyšší úrovně zahrnují předchozí kontroly. Level max se může po aktualizaci změnit, proto vyžaduje pravidelnou péči.
- Baseline
- Umožní postupné zavedení ve starším projektu. Je to řízený dluh, ne soubor, který se má bezmyšlenkovitě znovu generovat.
Výhody a omezení
Silná kontrola, ne neomylný důkaz správnosti
Přínosy
- typové rozpory se objeví dříve než v prohlížeči nebo produkci
- refaktoring rozhraní dohledá závislá místa
- přesnější kontrakty pomáhají IDE i dalšímu vývojáři
- kontrolu lze rychle a opakovaně spouštět v CI
Omezení
- nezná budoucí data z databáze ani skutečné chování externího API
- dynamické metody, reflexe a neúplná metadata snižují přesnost
- široká baseline a globální ignore mohou skrýt nové chyby
- zelený běh nenahrazuje business test ani bezpečnostní review
Hranice použití
Chybu je lepší popsat přesně než ji globálně ignorovat.
Pokud analyzátor hlásí problém u funkčního dynamického kódu, často chybí typ třetí strany, podpora frameworku nebo přesný kontrakt u zdroje dat. Lepší je doplnit stub, rozšíření nebo nativní typ než vypnout celou kategorii pravidel.
U rozsáhlého staršího systému má smysl postupný přechod. Baseline potlačí zdokumentované stávající nálezy; CI musí selhat na nových a baseline se má postupně zmenšovat, jinak se z ní snadno stane trvalé vypnutí kontroly.
Na co myslet
Analýza funguje jen s důvěryhodnými vstupy
Kontrola má být součástí běžné práce, ne občasný report bez vlastníka.
- nativní typy jako výchozí kontrakt
- přesný PHPDoc u kolekcí a generických nástrojů
- frameworková rozšíření a konfigurace odpovídající projektu
- CI, které blokuje nové chyby
- průběžně zmenšovaná a zdůvodněná baseline
Časté otázky
Co statická analýza ověřuje
Nahrazuje statická analýza automatizované testy?
Ne. Analýza hledá typové a strukturální rozpory bez spuštění scénáře. Test ověřuje konkrétní chování, pravidla a spolupráci s infrastrukturou.
Jaký je rozdíl mezi PHPStanem a PHPUnitem?
PHPStan prochází zdrojový kód a vyhodnocuje typy a možné chyby. PHPUnit spouští připravené testy a ověřuje očekávaný výsledek konkrétního chování.
Má smysl používat level max hned od začátku?
U nového dobře typovaného projektu ano, pokud tým nálezy průběžně opravuje. U staršího systému může být praktičtější postupný přechod a pečlivá baseline.
Je PHPDoc dostatečně spolehlivý?
Pomáhá hlavně u kolekcí a generik, ale vychází z deklarovaného kontraktu. Proto mají přednost správné nativní typy a přesná informace u zdroje dat.
Jak statickou analýzu používám v praxi
Každá kontrola kvality pokrývá jiný druh rizika.
PHPStan na vysoké úrovni používám vedle unit a integračních testů jako součást běžného vývojového workflow.