PHPStan: Kontrola sémantiky
Jazyky s explicitní kompilací můžou v tomto kroku dělat všelijaké pokročilé kontroly a kompilaci v případě něčeho podezřelého prostě zastavit. Dělá to třeba Java, která na tento krok dovoluje napojit i další kontroly. Takže existují projekty jako Error Prone od Google, který momentálně dělá 606 dalších kontrol potenciálně chybového kódu.
V PHP máme situaci jinou. Kód se kompiluje až těsně před spuštěním a asi bychom nebyli úplně rádi, když by se stránka nezobrazila třeba jen proto, že jsme napsali return;;
(druhý středník vyvolá chybu nedosažitelný kód). Předem můžeme pomocí php -l
udělat jen kontrolu syntaxe. Nicméně aby měl člověk klid v duši, tak by to chtělo udělat i nějaké další kontroly. Já jsem si před 17 lety napsal jednoduchý skript, který zkontroluje, jestli kód nepoužívá neinicializovanou proměnnou. Spouštěl jsem ho např. vždycky poté, kdy jsem část kódu přesunul do samostatné funkce. Dnes už s vyčleněním kódu do funkce pomůžou IDE, ale když uděláte pouhé copy/paste, tak se může snadno stát, že nějakou proměnnou v kódu použitou zapomenete předat funkci jako parametr.
Od té doby situace značně pokročila a dovednosti statických analyzátorů šly hodně dopředu. Etalonem schopností je PHPStan, který vzniká v Česku. Nasadil jsem ho nedávno na Adminer a i jeho netradičně strukturovaným kódem se PHPStan prokousal se ctí. Nejdůležitější je, že jeho nasazení odhalilo skutečné chyby. V několika případech mě také dokopalo k refaktoringu, díky kterému je daný kód teď lepší.
Co se mi hodně líbilo, jsou úrovně chyb. Začal jsem na úrovni 0, vyřešil všechny její chyby a pokračoval na další level. Nečekal bych, že se dá gamifikovat i tak otravná činnost jako hledání chyb. Ale skutečně jsem se několikrát dostal do situace, že jsem chtěl co nejrychleji opravit chyby jedné úrovně, abych zjistil, co mě čeká na úrovni další. Skončil jsem na úrovni 6, sedmičku jsem přeskočil a zvlášť zapnul ještě osmičku. Některé chyby jsem se rozhodl ignorovat, v kódu mám třeba fread($fp, 1e6)
, což se PHPStanu nelíbí, protože na místo celého čísla posíláme float
. Skutečný problém to ale nezpůsobí. Nic ale nebrání tomu výjimku v budoucnu smazat a kód přepsat tak, aby byl PHPStan spokojený.
PHPStan si neporadí s některými podivnostmi, např. s tímto kódem, který se dříve používal pro nahrávání pluginů:
<?php function f() { class C {} return new C; // PHPStan: Instantiated class C not found. } ?>
Také očekává, že nebudete přistupovat k neexistujícím prvkům pole:
<?php $a = array(1); if ($a[rand()]) { // PHPStan: If condition is always true. } ?>
Kód musíte přepsat, aby volal isset()
.
Nejprve jsem chtěl takovéto okrajové případy nahlásit, ale pak jsem se podíval na 1300 otevřených issues a řekl jsem si, že s takovýmito blbostmi nebudu autora PHPStanu Ondřeje Mirtese otravovat. Ondra se totiž vydal na odvážnou cestu a zkouší se tvorbou open-source živit. Muselo chtít velkou odvahu opustit práci a začít to dělat na plný úvazek. Přeji, ať to vyjde!
Vložit komentář

