PHP CodeSniffer - kód který nesmrdí

(publikováno 23.12.2019) 2 PHP, Kvalita kódu

Pro přehlednost a udržitelnost celé aplikace je vhodné dodržovat nějaké standardy v psaní kódu. A PHP CodeSniffer s tím dokáže pomoct. Na základě existujících sniffů jsem definoval vlastní set pravidel, který používám na svých projektech. A mimo jiné používá také pravidla Slevomatu.

PHP CodeSniffer - kód který nesmrdí

Stejně jako Stylelint slouží k dodržování pravidel pro CSS, Sass apod. PHP CodeSniffer dokáže kontrolovat a případně i opravovat kódovací standardy v PHP. Obsahuje i pravidla pro validaci JavaScriptu či CSS, osobně jsem to ale nezkoušel využít.

Již základní balíček obsahuje obrovské množství pravidel i celých sad standardů. Navíc je možné si další pravidla doinstalovat. Existují celé balíky pro Symfony, Laravel, WordPress a mnoho dalších. Pro své projekty jsem si sestavil vlastní set pravidel, která s malými výjimkami nyní používám.

Obrovskou nevýhodou CodeSnifferu je neodstatečná dokumentace jednotlivých sniffů. Pokoušel jsem se k pravidlům přidat komentář, popisující chování sniffu. Vše ostatní je popsáno na Wiki CodeSnifferu. Částečným řešením může být vygenerování dokumentace k použitým sniffům pomocí ./vendor/bin/phpcs --standard=./phpcs.xml --generator=HTML. Ne všechny ale tuto dokumentaci mají, ty od Slevomatu pak vůbec. Díky za zajímavý tip v komentáři od Petra

Definice pravidel a spouštění

CodeSniffer obsahuje 2 základní spustitelné soubory. Prvním z nich je phpcs, který spustí kontrolu kódu. Druhým je pak phpcbf, ten se pokusí opravit kód, který standardům odporuje. Ne vše však dokáže opravit. Vlastní set pravidel je založený na PSR2 a PSR12 základech, doplněné o relativně striktní pravidla Slevomatu

Instalace CodeSnifferu je možná pomocí Composeru i globálně, osobně ale preferuji instalaci lokální. Stejně tak možností spouštění je mnoho, dle mého ovšem vítězí vlastní phpcs.xml soubor, do kterého je možné celou konfiguraci vložit. Zde je ukázka instalace vlastního rulesetu, který v závislostech má kromě CodeSnifferu také zmíněné sniffy Slevomatu.

composer require --dev arxeiss/coding-standards

# Spouštění PHPCS s lokálním souborem obsahující pravidla
# Ukázkový obsah souboru je níže
./vendor/bin/phpcs --standard=./phpcs.xml

# Spouštění code fixeru
./vendor/bin/phpcbf --standard=./phpcs.xml

Vlastní konfigurace v phpcs.xml

Do lokálního souboru umístěného v rootu projektu lze vložit vše, co by jinak muselo být zmíněno v příkazové řádce. Proto mě tato metoda připadá výhodnější. Ukázkový soubor phpcs.xml může vypadat tak, jak je znázorněno níže. Vložena jsou všechna pravidla, která používám. Je ale možné některé vyloučit či si přidat úplně nové. Výhodné především pro staré projekty může být vkládání pravidel po částech, jak je popsáno v Readme v sekci Groups of sniffs.

Protože nesoudím codebase na základě používání mezer nebo tabulátorů, připravil jsem ruleset aby zvládal obojí. Změna je jen vložením phpcs-spaces.xml nebo phpcs-tabs.xml.

<?xml version="1.0"?>
<ruleset xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" name="Custom Ruleset">
    <file>./app</file> <!-- Složky a soubory ke kontrole -->
<file>./config</file> <arg name="basepath" value="."/> <!-- Odebrat globální část z adresy souboru při výpisu --> <arg name="colors"/> <!-- Zobrazit výpis s barvami --> <arg value="p"/> <!-- Zobrazit postup kontroly --> <arg value="s"/> <!-- Zobrazit v reportu jméno Sniffu který reportoval chybu --> <!-- Vložení základního pravidla obsahující veškeré sniffy - odsazení pomocí mezer --> <rule ref="./vendor/arxeiss/coding-standards/Rules/phpcs-spaces.xml"> <!-- Lze také vyloučit některá pravidla --> <exclude name="Generic.Files.LineLength.MaxExceeded"/> <exclude name="SlevomatCodingStandard.Namespaces.FullyQualifiedGlobalFunctions.NonFullyQualified"/> <!-- Trailing comma při volání funkcí je podporována až od PHP 7.3 --> <exclude name="SlevomatCodingStandard.Functions.TrailingCommaInCall"/> </rule> <!-- Lze přidat další striktní pravidla od Slevomatu --> <!-- <rule ref="./vendor/arxeiss/coding-standards/Rules/phpcs-strict.xml"> </rule> --> </ruleset>

Pozor na některá pravidla a jak na ně vyzrát

Základní pravidla definována v phpcs-spaces.xml jsem s drobným otestováním byl schopen aplikovat i na staré projekty bez vzniku nových chyb. Další pravidla ze souboru phpcs-strict.xml ale mohou jednoduše způsobit hromadu chyb. Převážně strict_types a type hinty mohou generovat chyby v jinak "bezchybném" kódu. V některém z příštích článků bude zmíněn další nástroj, který pomůže v objevování i těchto chyb.


A teď hurá do zkrášlování kódu. Zkušenosti s lintery či přímo PHPCS sdílejte v komentářích.

K tomuto článku již není možné přidávat další komentáře

Komentáře

> Obrovskou nevýhodou CodeSnifferu je neodstatečná dokumentace jednotlivých sniffů

Většina oficiálních sniffů má dokumentaci psanou v XML a nechá se pak vygenerovat Style Guide. Výstup vypadá třeba takto: https://github.com/slimapi/.../standard.md

Děkuji za zajímavý tip. O této funkcionalitě jsem nevěděl a informaci jsem do článku doplnil.

Celé to má ale vadu, že dokumentaci nevidím, než Sniff použiji. A například u Sniffu LineLength je výsledná dokumentace docela zbytečná: https://github.com/slimapi/.../standard.md#line-length . Nedozvím se ani, že tento Sniff má nějaké parametry, kterými jej můžu konfigurovat.