Slide 1

Slide 1 text

Coding Standard Ondřej Mirtes PHP Prague, 3. června 2016

Slide 2

Slide 2 text

Code review Bez code review si neumím představit vývoj. Každý kód, co jde do masteru, by měli vidět alespoň dva lidé. Klesne vám míra WTF a kódu bude rozumět víc lidí.

Slide 3

Slide 3 text

Code review • Kód dělá to, co má • Nezabije servery • Splňuje SOLID • Smysluplně rozšiřuje aktuální kód • ... • Je čitelný • Naformátovaný podle dohodnutých pravidel Poslední dva body jdou automatizovat, šetří to práci při code review. Pravidla jdou formalizovat. Všechen kód by měl vypadat stejně a nemělo by být poznat, kdo ho psal, pracují s ním všichni.

Slide 4

Slide 4 text

Coding standardem proti bugům if ($isFoo && $isBar)
 doSomething(); Kromě sjednocení podoby kódu lze pomocí coding standardu i zamezit některým bugům. Okolo ifu byste vždy měli mít složené závorky {}, i když obsahuje (právě teď) pouze jeden příkaz.

Slide 5

Slide 5 text

Coding standardem proti bugům if ($isFoo && $isBar) {
 doSomething();
 }

Slide 6

Slide 6 text

Coding standardem proti bugům if ($foo == 0) {
 
 } Nepřesná porovnání jsou zdrojem mnoha problémů. Zde např. bude vyhodnocena podmínka na true, pokud $foo bude jakýkoli string nezačínající číslicí.

Slide 7

Slide 7 text

Coding standardem proti bugům if ($foo === 0) {
 
 } Kdykoli někde vidím == nebo !=, tak to interpretuji jako "vůbec nevím, co v té proměnné vlastně je".

Slide 8

Slide 8 text

Přehlednější diffy $arr = [
 1,
 2
 ]; Coding standard kromě snížení chybovosti a zpřehlednění kódu má pozitivní dopad i na verzování. Čárka za posledním prvkem víceřádkového pole vede k přehlednějším diffům.

Slide 9

Slide 9 text

Přehlednější diffy $arr = [
 1,
 - 2 
 + 2,
 + 3 
 ]; Přidal jsem jeden prvek do pole, ale diff této změny je nepřehledný.

Slide 10

Slide 10 text

Přehlednější diffy $arr = [
 1,
 2,
 ];

Slide 11

Slide 11 text

Přehlednější diffy $arr = [
 1,
 2,
 + 3,
 ]; S čárkou za posledním prvkem už dává smysl.

Slide 12

Slide 12 text

Continuous Integration • Aplikaci lze vůbec spustit – nainstalovat závislosti, zkompilovat DI kontejner… • Syntax errory: php -l • Coding standard • Testy • Další kontroly - např. doctrine orm:validate-schema • Kompilace a kontrola CSS, JavaScriptu, …

Slide 13

Slide 13 text

Continuous Integration

Slide 14

Slide 14 text

PHP_CodeSniffer squizlabs/php_codesniffer

Slide 15

Slide 15 text

ruleset.xml 
 
 
 
 ...
 
 CodeSniffer se bohužel konfiguruje pomocí XML. Do lze uvést buďto cestu k dalším rulesetům (a "includovat" tak další standardy) nebo konfigurovat konkrétní sniffy.

Slide 16

Slide 16 text

ruleset.xml 
 
 
 
 
 Při includnutí dalšího rulesetu lze vynechat některá pravidla, která obsahuje, v případě, že vám nevyhovují.

Slide 17

Slide 17 text

ruleset.xml 
 
 
 
 
 Konkrétní sniffy lze konfigurovat, pokud to umožňují. Tato nastavení se propisují do public properties před spuštěním daného sniffu.

Slide 18

Slide 18 text

Kde shánět sniffy? • github.com/squizlabs/PHP_CodeSniffer
 nebo: • edorian.github.io/php-coding-standard-
 generator/#phpcs Sniffy se shání velmi těžko. Samotný repozitář CodeSnifferu jich hromadu obsahuje, musíte se ale orientovat podle jejich názvu nebo implementace, nejsou nikde sepsané. Někdy je snazší si ho napsat sám

Slide 19

Slide 19 text

Z čeho se sniff skládá • Public properties – konfigurace • register() • process(
 \PHP_CodeSniffer_File $phpcsFile,
 $tokenPointer
 )

Slide 20

Slide 20 text

Tokenizace zdrojáku public function doFoo(): Foo
 {
 return $this->doBar();
 }
 
 T_PUBLIC, T_WHITESPACE, T_FUNCTION, T_WHITESPACE, T_STRING, T_OPEN_PARENTHESIS, T_CLOSE_PARENTHESIS, T_COLON, T_WHITESPACE, T_RETURN_TYPE, T_WHITESPACE, T_OPEN_CURLY_BRACKET, T_WHITESPACE, T_RETURN, T_WHITESPACE, T_VARIABLE, T_OBJECT_OPERATOR, T_STRING, T_OPEN_PARENTHESIS, T_CLOSE_PARENTHESIS, T_SEMICOLON, T_WHITESPACE, T_CLOSE_CURLY_BRACKET

Slide 21

Slide 21 text

Jaké tokeny mě zajímají? public function register()
 {
 return [
 T_IF,
 T_ELSEIF,
 T_DO,
 ];
 }

Slide 22

Slide 22 text

Pro každý token, na který PHPCS narazí,
 se zavolá: public function process(
 \PHP_CodeSniffer_File $phpcsFile,
 $tokenPointer
 ) {
 $tokens = $phpcsFile->getTokens();
 $token = $tokens[$tokenPointer];
 }

Slide 23

Slide 23 text

Pole s tokenem obsahuje: "content" => "doBar",
 "code" => 319, // T_STRING
 "type" => "T_STRING",
 "line" => 8,
 "column" => 17,
 "conditions" => [
 2 => 361, // T_CLASS
 12 => 346, // T_FUNCTION
 ],

Slide 24

Slide 24 text

Metody k dispozici $tokenPointer = $phpcsFile->findNext(
 $types,
 $start,
 $end = null,
 $exclude = false,
 $value = null,
 $local = false
 );

Slide 25

Slide 25 text

Metody k dispozici $tokenPointer = $phpcsFile->findPrevious(
 $types,
 $start,
 $end = null,
 $exclude = false,
 $value = null,
 $local = false
 );

Slide 26

Slide 26 text

Označení chybného zdrojáku $phpcsFile->addError(
 $error,
 $tokenPointer,
 $code = '',
 ...
 ); Pokud sniff reportuje více různých druhů chyb, $code slouží k jejich rozlišení. Můžete pak excludovat konkrétní code a nikoli celý sniff.

Slide 27

Slide 27 text

Jak naimplementovat kontrolu? $arr = [
 1,
 2
 ]; Zaregistruju se na otevírací závorku pole a hledám konečnou. Musím ale počítat se zanořeným polem, takže mě zajímá závorka na stejné úrovni (ve stejné hloubce). Jakmile na ní narazím, hledám první newhitespacový token, měla by to být čárka. Pokud není, nahlásím chybu.

Slide 28

Slide 28 text

Jak naimplementovat kontrolu? if ($isFoo && $isBar)
 doSomething(); Zaregistruju se na T_IF, najdu jeho otevírací závorku a pak hledám konečnou. Opět počítám se zanořenými podmínkami. Po konečné závorce by měl být první newhitespacový token {. Pokud není, nahlásím chybu.

Slide 29

Slide 29 text

Jak spustit PHPCS? vendor/bin/phpcs
 --standard=ruleset.xml
 --extensions=php
 --tab-width=4
 -s // show sniff codes
 -p // show progress
 app
 tests

Slide 30

Slide 30 text

Samoopravné sniffy ---------------------------------------------------------------------- FOUND 1 ERROR AFFECTING 1 LINE ----------------------------------------------------------------------
 38 | ERROR | [x] Multiline arrays must have a trailing comma after the
 | | last element
 | | (SlevomatCodingStandard.Arrays.TrailingArrayComma)
 ----------------------------------------------------------------------
 PHPCBF CAN FIX THE 1 MARKED SNIFF VIOLATIONS AUTOMATICALLY
 ---------------------------------------------------------------------- Pokud je u chybové hlášky [x], znamená to, že umí prohřešek CodeSniffer i opravit.

Slide 31

Slide 31 text

Samoopravné sniffy vendor/bin/phpcbf
 --standard=ruleset.xml
 --extensions=php
 --tab-width=4
 -s // show sniff codes
 -p // show progress
 app
 tests

Slide 32

Slide 32 text

Slevomat Coding Standard • Nepoužité privátní properties a metody • Seřazené uses • Nepoužité uses • Zakázané yoda podmínky • Sniffy ohledně namespaces • Chystané PHP 7-specific sniffy (2.0) github.com/slevomat/coding-standard

Slide 33

Slide 33 text

@OndrejMirtes