DressCode
DressCode je dress code pro váš PHP kód. Hlídá jeho styl, většinu nálezů rovnou opraví a kód umí i aktualizovat: přepíše ho na novější PHP, od PHP 8.0 až po PHP 8.6, i na nové verze knihoven. Pracuje nad bezztrátovým syntaktickým stromem, takže změní jen to, na co sáhne, a zbytek souboru zůstane bajt po bajtu stejný. Sám žádný styl nenosí, obléká kód podle standardu: PER Coding Style 3.1, PSR-12, Nette Coding Standard nebo Symfony. A co chcete mít jinak, napíšete klíč po klíči, tak jak to v kódu vypadá, klidně pro každou část projektu jinak.
Léta jsem používal PHP CS Fixer i PHP_CodeSniffer a bral je jako hotovou věc. Pak jsem potřeboval jedno nové pravidlo a zjistil, kolik práce dá napsat ho, když nástroj vidí jen ploché pole tokenů a strukturu kódu si musí domýšlet. DressCode vznikl proto, aby se pravidlo dalo napsat za odpoledne a aby se dalo věřit tomu, co opraví.
Konfigurace, která popisuje kód
Nástroje na styl kódu mají stovky pravidel a DressCode není výjimka: jen vestavěných je přes dvě stě. Do konfigurace je ale nejmenujete. Píšete do ní, jak váš kód vypadá, věc po věci: klíč jmenuje věc v kódu a hodnota říká, jak se píše.
use:
- perCs
- modernizations
braces:
position:
class: nextLine
spacing:
concatenation: '$a.$b'
qualification:
function:
global: bare
optimized: imported
Dá se to číst nahlas: složená závorka třídy na dalším řádku, tečka bez mezer, globální funkce holé a ty, které PHP optimalizuje, importované. Ty poslední dva řádky v PHP CS Fixeru žádné nastavení neříká. Vyjdou ze souhry dvou pravidel:
'native_function_invocation' => [
'include' => ['@compiler_optimized'],
'scope' => 'namespaced',
'strict' => true,
],
'global_namespace_import' => ['import_functions' => true],
První pravidlo napíše lomítko před funkce, které optimalizuje kompilátor, a ostatním ho vezme, druhé pak každé lomítko převede na import. Nad týmž souborem dají obě konfigurace stejný kód, jen k tomu v PHP CS Fixeru vede úvaha, ne věta. PHP_CodeSniffer se Slevomatem umí lomítko před optimalizované funkce, nebo import všech globálních funkcí, ale import jen těch optimalizovaných ne.
Psát stovky klíčů přitom nemusíte, protože konfigurace stojí na dvou otázkách. Jak má kód vypadat? To je
standard, jeden, a vyberete ho jménem. Co po kódu chcete kromě vzhledu? To jsou sady: modernizations,
deprecations, cleanup, correctness, types a
compilerOptimizations. Sada jmenuje záměr, ne výčet klíčů, a roste: když se DressCode naučí novou
modernizaci, sada ji přinese bez jediného řádku v konfiguraci. Na zbytek stačí klíč, a kde nemá platit ani to, co
říká standard, napíšete keep.
Celou cestu ke klíči, třeba braces.position.class, uvidíte u každého nálezu ve výpisu, takže víte, co
nastavit, potlačit, nebo si nechat vysvětlit příkazem dresscode explain braces.position.class. A než klíč
zapíšete natrvalo, vyzkoušíte ho na jeden běh: dresscode fix --set cleanup.is_null=forbidden ho přidá
k vaší konfiguraci a jeho změny vyjdou rovnou zformátované, na jeden čistý commit. Všechny sekce a jejich klíče
popisuje Struktura konfigurace.
Nejen styl, ale i aktualizace kódu
Nástroj, který kódu rozumí, se nemusí zastavit u mezer. Když zvednete verzi PHP v composer.json, sada
modernizations přepíše kód na to, co nová verze přinesla, a DressCode ho v témž běhu zformátuje podle
vašeho standardu:
return trim(strtolower(strip_tags($title)));
return $title |> strip_tags(...) |> strtolower(...) |> trim(...);
Stejně převede kód při aktualizaci knihoven: pro Nette nese
balíček dresscode/rules-nette migrace všech dvaceti knihoven, u většiny od verze 3.0 po současnou,
přejmenované třídy, konstanty, metody i parametry, a balíčky pro další ekosystémy přibývají. A když máte
v projektu PHPStan, DressCode se ho ptá na typy, takže přepíše i zastaralé API podle toho, čím proměnná opravdu je.
Styl i přechod na novou verzi tak obstará jeden nástroj s jednou konfigurací a jedním diffem.
Pokrytí PER Coding Style a PSR-12
Že nástroj umí standard, se napíše snadno, a tak jsem výsledek nechal posoudit konkurenci. Laravel opravený presetem
perCs dostal PHP CS Fixer s vlastní sadou pro PER Coding Style a v 1 696 souborech změnil ještě 9 míst.
Obráceně najde DressCode po PHP CS Fixeru 1 201 míst, kde PER Coding Style chce něco jiného, třeba jednu položku na
řádek nebo čárku za víceřádkovým seznamem. U PSR-12 najde DressCode po phpcbf ještě 772 míst, mezi nimi
chybějící viditelnost konstant, kterou phpcbf ohlásí, ale doplnit neumí. Čísla pro Symfony i to, co zbylo na
druhé straně, rozebírá stránka Jak DressCode
funguje.
Rychlost proti PHP CS Fixeru a PHP_CodeSniffer
DressCode je dělaný k tomu, aby běžel po každé úpravě souboru, a tam rozhoduje čas jednoho souboru: je to zhruba
třetina až polovina času PHP CS Fixeru, u malého souboru 118 ms proti 323 ms. Rychlejší je i nad celým projektem, když
dělá stejnou práci. S rozhodnutími, která odpovídají sadě PER Coding Style z PHP CS Fixeru, mu stačí 64 až 90 %
času PHP CS Fixeru v jednom procesu a 46 až 64 % v paralelních procesech, nad kódem Laravelu, WordPressu, Symfony a Nette.
Symfony s vlastní konfigurací PHP CS Fixeru, převedenou příkazem import, zkontroluje za 56 % jeho času
(14,2 s proti 25,3 s), i když PHP CS Fixer tam navíc pouští přes sto pravidel pro phpDoc a PHPUnit, která
DressCode nemá.
Preset perCs dělá víc než zmíněná sada: navíc láme dlouhé signatury, podmínky, řetězy volání a pole
na řádky a opravuje velikost písmen ve jménech. Preset proti presetu proto běží nad Laravelem 72 % času PHP CS Fixeru a
nad WordPressem 118 %, protože tam mají rozhodnutí navíc nejvíc práce.
Proti PHP_CodeSniffer je rozdíl vidět při opravě: dresscode fix potřebuje 36 až 54 % času, který na
PSR-12 spotřebuje phpcbf. Samotné hlášení zvládne phpcs rychleji, protože
dresscode check si opravy počítá v paměti i při kontrole. A přepis na novější PHP trvá zlomek toho, co
Rector, nad Symfony 3.4 1,6 s proti 128,5 s, a s typy z PHPStanu je pořád
rychlejší: nad Laravelem 4,4 s proti 10,5 s s nahřátou cache PHPStanu a 9,0 s proti 195 s se studenou.
Měřeno v říjnu 2026 na PHP 8.5 proti PHP CS Fixeru 3.95, PHP_CodeSniffer 4.0 a Rectoru 2.6, medián tří běhů.
Kudy dál
- Začínáme s DressCode instalace, první kontrola a první oprava.
- Konfigurace standard, sady a klíče, které říkají, jak kód vypadá.
- Přechod na novější PHP jak DressCode přepíše kód od PHP 8.0 po PHP 8.6.
- Aktualizace knihoven migrace Nette a dalších knihoven v jednom běhu.
- Přechod na DressCode pokud dnes používáte PHP CS Fixer, PHP_CodeSniffer nebo Slevomat.
- Jak napsat vlastní pravidlo pokud vám v katalogu něco chybí.
Používání
- Jak DressCode funguje strom místo tokenů, rozhodnutí místo pravidel, průchody a slovníček pojmů.
- Typy z PHPStanu co DressCode dokáže, když se může ptát PHPStanu na typy vašeho kódu.
- Funkce a konstanty ve jmenných prostorech proč je
strlen()ve jmenném prostoru dvojznačné a jak tu nejistotu DressCode odstraní. - Optimalizace funkcí a konstant jaké zkratky PHP u volání funkcí a u konstant bere, co je vypne a jak kód zapsat, aby platily.
- Potlačení a baseline výjimky na řádku, v souboru a pro cestu, a baseline pro to, co kód zatím nesplňuje.
- Příkazová řádka příkazy, přepínače, formáty výstupu, exit kódy.
Reference
- Struktura konfigurace všechny sekce a jejich klíče s hodnotami a ukázkami.
- Standardy a sady co přesně rozhodují PER Coding Style, PSR-12, Nette, Symfony a šest sad.
Rozšíření a integrace
- Rozšiřování DressCode, vlastní pravidlo, pravidlo do detailu, pravidla pro bílé znaky, testování pravidel.
- Průběžná integrace, Git hooky a agenti.
- PhpSyntax bezztrátový syntaktický strom, na kterém DressCode stojí, jako samostatná knihovna.