Slovník pojmů
PHPStan
PHPStan kontroluje typové kontrakty a možné chyby ještě před spuštěním scénáře. V PHP projektu tak doplňuje testy, coding standards i běžný syntax lint.
Stručná definice
Analyzátor, který rozumí typům a toku PHP kódu.
Obecné heslo Statická analýza kódu vysvětluje princip. PHPStan je jeho konkrétní implementace pro PHP: pracuje s nativními typy, PHPDoc, Composer autoloadingem a konfigurací projektu. Z nich vyvozuje, jaké hodnoty mohou na dané místo přijít a zda s nimi kód zachází bezpečně.
Nástroj aplikaci nespouští ani neověřuje, zda obchodní pravidlo odpovídá zadání. Odhaluje ale například volání metody nad nullable hodnotou, chybný typ argumentu, neexistující symbol, neplatný návratový typ, neúplně popsanou kolekci nebo část nedosažitelného kódu.
Použití
Kdy PHPStan přináší nejvíc zpětné vazby
Nejlépe funguje tam, kde jsou kontrakty popsané přesně a kontrola běží při každé změně.
- refaktoring rozhraní, DTO, repository a aplikačních služeb
- kontrola nullable hodnot, návratových typů a typů argumentů
- popis kolekcí a generických pomocných tříd pomocí PHPDoc
- zpřesnění dynamických částí frameworku pomocí rozšíření nebo stubů
- automatická kontrola pull requestu v CI před sloučením změny
Praktický příklad
Kód, který PHP spustí, ale zákazník nemusí existovat
Metoda repository oprávněně vrací ?Customer, protože pro externí ID nemusí být záznam uložený. Pokud aplikační služba bez kontroly čte e-mail, při nalezeném zákazníkovi poběží, ale při chybějícím skončí chybou. PHPStan upozorní na možné volání metody nad Customer|null ještě před spuštěním importu.
Oprava musí vyjádřit obchodní rozhodnutí: zákazníka vytvořit, import označit jako neúplný, nebo použít metodu s kontraktem konkrétní výjimky. Samotná analýza toto rozhodnutí nenahradí.
final class ImportOrder
{
public function __construct(private CustomerRepository $customers) {}
public function customerEmail(string $externalId): string
{
$customer = $this->customers->findByExternalId($externalId); // ?Customer
return $customer->email(); // PHPStan: Customer|null
}
}
Jak funguje
Od zdrojových souborů k nálezu
Přesnost výsledku závisí na kvalitě typových informací, ne jen na zvolené úrovni.
- Konfigurace Soubor phpstan.neon určí analyzované cesty, úroveň pravidel, include soubory a nastavení projektu.
- Symboly a metadata PHPStan načte známé třídy a funkce přes Composer, nativní typy, PHPDoc a případná rozšíření frameworku.
- Odvození typů Při průchodu větvemi sleduje možné hodnoty proměnných, návraty metod a platnost operací.
- Diagnostika Nález uvádí soubor, řádek a identifikátor chyby, aby jej šlo opravit nebo výjimečně zdůvodněně ignorovat.
- CI Stejný příkaz v pull requestu zastaví změnu, která přidá nový porušený kontrakt.
Co PHPStan kontroluje
Typové informace nad rámec běžného běhu PHP
Jde o kontrolu technických kontraktů. Nejde o formátování zdrojových souborů ani spuštění testovacích scénářů.
Nativní a odvozené typy
Vyhodnocuje parametry, návraty, vlastnosti, union a nullable typy i typy vzniklé po podmínkách.
PHPDoc a generika
Typové zápisy PHPDoc, například array<int, Order>, a tagy jako @template nebo @extends zachovají informaci o prvcích kolekce, kterou PHP v array nevyjádří.
Type aliases
Složitější opakovaný tvar dat lze pojmenovat aliasem, aby kontrakt DTO nebo pole zůstal čitelný a jednotný.
Úrovně přísnosti
Úrovně jsou kumulativní; max označuje nejvyšší úroveň daného vydání. Vyšší přísnost odhalí více rizik, ale vyžaduje přesnější typy.
Rozšíření a vlastní pravidla
Rozšíření pro Symfony, Doctrine, Nette, PHPUnit nebo Larastan zpřesní dynamické chování. Vlastní rule lze přidat pro opakovaně nechtěný vzor specifický pro projekt.
Jasné hranice nástrojů
Každý nástroj zachycuje jiný druh problému
Slučovat jejich odpovědnosti by vedlo k falešnému pocitu pokrytí.
- Statická analýza
- PHPStan je konkrétní analyzátor; obecné heslo popisuje princip nezávisle na produktu.
- PHPUnit
- PHPUnit spouští připravené testy. PHPStan žádný scénář nespouští; může najít chybu i v nevolané větvi.
- PHP_CodeSniffer
- PHPCS kontroluje coding standards, například mezery, importy nebo týmové konvence. Nevyhodnocuje běžně možné typy hodnot.
- Syntax lint
- php -l ověří, že parser soubor přijme. Neodhalí většinu chyb kontraktů mezi třídami.
- Formátování
- Automatický formátovač upraví zápis kódu. PHPStan kód nepřepisuje a neřeší estetickou podobu souboru.
Výhody a omezení
Důležitá kontrola, nikoli důkaz správnosti aplikace
Přínosy
- rychlá zpětná vazba před běžným spuštěním aplikace
- bezpečnější refaktoring díky dohledání závislých kontraktů
- přesnější typy pomáhají také IDE a dalším lidem v týmu
- opakovatelná kontrola v CI nezávislá na pozornosti při code review
Omezení a chyby
- statická analýza nenahradí unit, integrační ani end-to-end test
- příliš obecné mixed a neúplný PHPDoc snižují hodnotu výsledku
- nejvyšší úroveň sama nezaručí dobrý doménový návrh
- globální ignore nebo bezmyšlenkovitě rostoucí baseline mohou skrýt nové chyby
Konfigurace a zavádění
Přísnost má odpovídat schopnosti nálezy opravovat.
Konfigurace obvykle obsahuje analyzované cesty, úroveň a include soubory pro rozšíření. U nového projektu dává smysl nastavit ambiciózní úroveň a držet výsledek bez chyb. U starší aplikace lze přísnost navyšovat postupně, pokud tým rozumí tomu, co konkrétní nálezy znamenají.
Baseline dočasně potlačí známé existující nálezy a dovolí blokovat nové. Nemá se ale automaticky znovu generovat při každém běhu: ztratila by roli řízeného technického dluhu. Jednotlivou legitimní výjimku je vhodnější ignorovat přes identifikátor chyby, v úzkém rozsahu a s vysvětlením.
Praktická pravidla
Jak z kontroly získat skutečnou hodnotu
Cílem není co nejvyšší číslo v konfiguraci, ale důvěryhodné kontrakty a rychlé nalezení nových regresí.
- nejprve opravit kontrakt u zdroje dat místo opakovaných inline @var
- používat nativní typy a PHPDoc pro kolekce či generika
- zvolit a aktualizovat jen relevantní frameworková rozšíření
- držet baseline i ignoreErrors malé, konkrétní a zdůvodněné
- spouštět stejnou konfiguraci lokálně i v CI
Časté otázky
Co od PHPStanu očekávat
Nahrazuje PHPStan PHPUnit?
Ne. PHPStan analyzuje kód bez spuštění scénáře. PHPUnit spouští testy a ověřuje konkrétní očekávané chování, včetně spolupráce komponent podle zvoleného typu testu.
Je PHPStan totéž co PHP_CodeSniffer?
Ne. PHP_CodeSniffer kontroluje coding standards a část nálezů umí opravit přes PHPCBF. PHPStan vyhodnocuje typové kontrakty a možné technické chyby; kód s perfektním stylem může mít stále chybný typ.
Má projekt vždy používat level max?
Je to rozumná volba, pokud tým umí udržet výsledek bez nových chyb a aktualizace nástroje. U starší aplikace může být lepší postupné navyšování úrovní nebo dočasná řízená baseline.
Kdy je vhodné chybu ignorovat?
Jen pro konkrétní zdůvodněnou výjimku, například nepopisovatelné dynamické chování třetí strany. Přednost má oprava typu u zdroje dat, stub, rozšíření nebo přesnější kontrakt.
Jak PHPStan používám v praxi
Typové kontrakty kontroluji vedle testů a architektury.
PHPStan na nejvyšší úrovni se strict rules používám jako součást běžné zpětné vazby při vývoji PHP aplikací.