Slide 1

Slide 1 text

PHPStanʹΑΔ ܧଓత੩తղੳ @hiraku

Slide 2

Slide 2 text

ࣗݾ঺հ • த໺ ୓ (@Hiraku) • https://github.com/hirak • גࣜձࣾϝϧΧϦ → ϝϧϖΠ • PHPྺ10೥͙Β͍ • Composerؔ࿈ͷൃදΛΑ͍ͯ͘͠·͢

Slide 3

Slide 3 text

2݄͔ΒϝϧϖΠࣾʹҟಈ͠·ͨ͠ • ۚ༥ؔ࿈ͷ৽نࣄۀΛߦ͏
 ϝϧΧϦͷάϧʔϓձࣾ • શํ໘ɺϝϯόʔืूதʂ

Slide 4

Slide 4 text

ʲએ఻ऴΘΓʳ

Slide 5

Slide 5 text

΋͘͡ • dynamic ͱ static • PHPStanͷ঺հ ~ϝϧΧϦͰͷ׆༻ࣄྫ • staticͱͷڑ཭ײ • ࣮ફɾܕ஫ऍ

Slide 6

Slide 6 text

ୈ1෦ dynamic ͱ static PHPStanʹΑΔܧଓత੩తղੳ

Slide 7

Slide 7 text

ྑ͍ίʔυ͔Ͳ͏͔ ΛݟۃΊΔ2ͭͷΞϓϩʔν dynamic / static

Slide 8

Slide 8 text

dynamic = ಈ͔ͯ͠ΈΔ • ςετ (ࣗಈ/खಈͲͪΒͰ΋) • ୅ද஋Λ༩࣮͑ͯߦˠ૝ఆ௨Γ͔൱͔ • ࢓༷ͷ֬ೝʹ΋࢖͑Δ

Slide 9

Slide 9 text

dynamicͷ೉఺ • ຊ౰ʹ࣮ߦ͞ΕΔͱࠔΔ৔߹͕͋Δ
 (ϛαΠϧൃࣹͱ͔) • શ෦ςετ͢Δͷ͸ແཧ
 (64bit intͷҾ਺㲈1844ژύλʔϯ) • ϞοΫΛ༻ҙͯ͠ɺ୅ද஋ΛબΜͰ…
 ޻෉͕ඞཁ

Slide 10

Slide 10 text

static = ಈ͔ͣ͞ʹಡΉ • ίʔυϨϏϡʔ / ੩తݕࠪ • ಈ͔͞ͳ͍ͷͰԿ΋ى͖ͳͯ҆͘৺ • ςετίʔυ͕ͳͯ͘΋ݕࠪՄೳ

Slide 11

Slide 11 text

staticͷ೉఺ • ϓϩάϥϛϯάݴޠ, ίʔυͷελΠϧʹ
 ΑͬͯɺͰ͖ΔϨϕϧ͕มΘΔ • ཧ࿦্ɺܾఆͰ͖ͳ͍छྨͷ໰୊͕͋Δ • ແݶϧʔϓ/ఀࢭੑͳͲ • (ϥΠεͷఆཧͱ͔Ͱάάͬͯʂ)

Slide 12

Slide 12 text

ͳͥ͜Μͳ࿩Λ ͍ͯ͠Δͷ͔

Slide 13

Slide 13 text

ϝϧΧϦͷ PHPίʔυͷ࿩

Slide 14

Slide 14 text

~2016೥·Ͱ •!"# ͷશαʔόʔαΠυϩδοΫ͕
 1ͭͷrepositoryͩͬͨ • ifͰ෼ذଟ਺ • ΤϯδχΞϦιʔεͷڞ༗Խ

Slide 15

Slide 15 text

2017೥ʹى͖ͨ͜ͱ •!ͱ"# ͷίʔυ͕෼཭ͨ͠ • ݕূൣғΛڱͯ͘͠։ൃεϐʔυUP • ࢖ͬͯͳ͍ίʔυͷ࡟আ͕ඞཁʹͳͬͨ

Slide 16

Slide 16 text

େྔͷίʔυ࡟আΛࢼΈΔ

Slide 17

Slide 17 text

Өڹൣғͷେ͖ͳमਖ਼

Slide 18

Slide 18 text

യવͱͨ͠ෆ҆

Slide 19

Slide 19 text

ൃੜͨ͠໰୊ • ϚχϡΞϧͰQA͢Δͱ͔͔࣌ؒΔ • ϦϑΝΫλϦϯά୲౰ऀ͕ϢχοτςετΛ ॻ͘ͱ͜Ζ͔Β࢝Ίͳ͍ͱ͍͚ͳ͍ • ϦϦʔεʹ༐ؾ͕ඞཁ

Slide 20

Slide 20 text

༐ؾ͕΄͍͠ʂ

Slide 21

Slide 21 text

ྑ͍ίʔυ͔Ͳ͏͔ ΛݟۃΊΔ2ͭͷΞϓϩʔν dynamic / static

Slide 22

Slide 22 text

staticํ໘͔Β΋߈Ί͍ͨ • ςετΛ૿΍͞ͳͯ͘΋࣮ߦͰ͖Δ • मਖ਼ྔ͕ଟͯ͘΋ػցͳΒશ෦ϨϏϡʔͯ͘͠ΕΔ • Ͳ͏ͤͳΒCIαʔόʔʹ૊ΈࠐΜͰɺக໋తͳ΋ͷ ͸CIΛࣦഊ͍ͤͨ͞ • PHPStorm͸༏ल͚ͩͲɺCIʹ૊ΈࠐΉͷ͕
 ೉͍͠

Slide 23

Slide 23 text

ୈ2෦ PHPStanͷ঺հ PHPStanʹΑΔܧଓత੩తղੳ

Slide 24

Slide 24 text

PHPStanͱ͸ • https://github.com/phpstan/phpstan • PHP Static Analysis Tool ͷུ • ಈ࡞ʹ͸PHP 7.1Ҏ্͕ඞཁ • PHP5ͷίʔυ΋ղੳͯ͘͠ΕΔ • nikic/php-parserϕʔεͰͷղੳΛߦ͏ (ͷͰׂͱݡ͍)

Slide 25

Slide 25 text

Phanͱͷҧ͍ • https://github.com/phan/phan • ͲͪΒ΋ࣅͨ͜ͱ͕Մೳ • ͪΐͬͱઃܭࢥ૝͕ҧ͏(͋ͱͰղઆ͠·͢)

Slide 26

Slide 26 text

※ϝϧΧϦͰPhanΛ
 ࠾༻͠ͳ͔ͬͨཧ༝ • PHPDocΛख͕͔Γʹ͢ΔͷͰɺPHPDoc Λ ͔ͬ͠Γॻ͍ͯͳ͍ͱπϥ͔ͬͨ • ext-ast Λඞཁͱ͢ΔͷͰऔΓճ͕͠ѱ͔ͬͨ • ʮͱΓ͋͑ͣɺ͜͜Ͱൃੜ͍ͯ͠Δ͜ͷΤϥʔ ͸ແࢹ͓ͯ͜͠͏ʯ͍ͬͯ͏ઃఆͷॊೈ͞

Slide 27

Slide 27 text

ݕग़ͯ͘͠ΕΔ໰୊ͷྫ • ม਺ͷະఆٛ • nullͷՄೳੑ͕͋ΔͷʹϝιουݺΜͰΔ • PHPDocͷߏจෆඋ • ܕͷෆඋશൠ

Slide 28

Slide 28 text

No content

Slide 29

Slide 29 text

div() should return int but returns float. floatͳΒOK

Slide 30

Slide 30 text

Install • composer require --dev phpstan/phpstan • phar൛΋͋Δ͠ɺglobal requireͯ͠΋୯ಠಈ ࡞͢Δ • docker hubʹ΋Πϝʔδ͕͋Δ • https://hub.docker.com/r/phpstan/phpstan/

Slide 31

Slide 31 text

※όʔδϣϯҧ͍ʹ஫ҙ • 2018೥3݄࣌఺ͷstable (0.9ܥ) ͱɺdev (1.0ܥ)͸ ͔ͳΓΦϓγϣϯʹҧ͍͕͋Γ·͢ • githubͷREADME.mdΛಡΉͱ͖͸஫ҙ • ͜͜Ͱ͸dev൛(1.0ܥ)Λϕʔεʹ࿩͠·͢ • composer global require "phpstan/phpstan:@dev" ͳͲͰೖΓ·͢

Slide 32

Slide 32 text

Run • ϓϩδΣΫτϩʔΧϧʹೖͬͯΕ͹
 $ vendor/bin/phpstan analyseͰىಈ • ղੳ͍ͨ͠σΟϨΫτϦʹͯɺphpstanίϚϯ υΛىಈ͢Ε͹ྑ͍

Slide 33

Slide 33 text

࣮ߦͨ͠ͱ͖ͷΠϝʔδ $ phpstan analyse Note: Using configuration file /Users/hiraku/src/github.com/hirak/ prestissimo/phpstan.neon.dist. 12/12 [▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓] 100% ------ ------------------------------------------------------------------- Line src/BaseRequest.php ------ ------------------------------------------------------------------- 23 PHPDoc tag @var has invalid value ([string => string]): Unexpected token "[", expected TOKEN_IDENTIFIER at offset 9 120 PHPDoc tag @param has invalid value ($io): Unexpected token "$io", expected TOKEN_IDENTIFIER at offset 18 120 PHPDoc tag @param has invalid value ($githubDomains): Unexpected token "$githubDomains", expected TOKEN_IDENTIFIER at offset 70 120 PHPDoc tag @param has invalid value ($gitlabDomains): Unexpected token "$gitlabDomains", expected TOKEN_IDENTIFIER at offset 99 ------ -------------------------------------------------------------------

Slide 34

Slide 34 text

Configure • ઃఆϑΝΠϧ͕͋Ε͹ɺ phpstan analyse ͩ ͚ͰղੳͰ͖Δ(1.0ܥ) • .neonͱ͍͏ɺYAMLͷΑ͏ͳઃఆϑΝΠϧΛ࢖͏ • stable൛(0.9ܥ)ͱɺdev൛(1.0ܥ)Ͱ͔ͳΓมߋ͕ ೖ͍ͬͯΔɻdev൛ͷํ͕ศར͞ˢˢ

Slide 35

Slide 35 text

1.0ܥͷphpstan.neon.distྫ • phpstan.neon→~.distͷ ॱʹ୳ͯ͠ಡΉ • .neon͸.gitignore͠ͱ͘ ͱڞಉ։ൃऀ͕޷͖ʹ֦ ுͰ͖Δ

Slide 36

Slide 36 text

CIͱͷ࿈ܞ • Τϥʔ͕͋ΔͱίϚϯυͷऴྃεςʔλε͕1ʹͳΔͷ Ͱɺࣦഊ൑ఆ͸༰қ • ϝϧΧϦͰ͸CircleCIΛ࢖ͬͯ2ஈ֊Ͱ࿈ܞ • ࠷௿ݶͷϧʔϧ͸CIࣗମΛམͱ͢ • ݫ͠Ίͷϧʔϧ͸reviewdogͰPull Requestʹίϝϯ τͤ͞Δ(CI͸མͱ͞ͳ͍)

Slide 37

Slide 37 text

reviewdogศར • http://haya14busa.com/reviewdog/

Slide 38

Slide 38 text

ϧʔϧΛΏΔΊΔํ๏ • levelΦϓγϣϯͰࡶʹࢦఆ • 0 ~ 7ɺmaxͱ͍͏ΤΠϦΞε΋͋Δ • https://github.com/phpstan/phpstan/tree/ master/conf

Slide 39

Slide 39 text

ஸೡʹϧʔϧΛΧελϜ • level͸ࢦఆͤͣʹ parameters
 .customRulesetUsed Λtrueʹ • rulesʹฒ΂Δ

Slide 40

Slide 40 text

ࡶʹ཈੍ • parameters
 .ignoreErrors
 Λ௥Ճ • ਖ਼نදݱͰΤϥʔ ϝο ηʔδΛϚον͞ ͤͯແࢹͰ͖Δ(!) ͱ͔ Λ௥Ճͨ͠Β શΤϥʔ཈ࢭʂ

Slide 41

Slide 41 text

ୈ3෦ staticͱͷڑ཭ײ PHPStanʹΑΔܧଓత੩తղੳ

Slide 42

Slide 42 text

No content

Slide 43

Slide 43 text

autoloadͷઃఆ͕͋Δ

Slide 44

Slide 44 text

autoloadͱ͸ • ಛఆͷؔ਺Λ࣮ߦͯ͠ϑΝΠϧΛ require_once͠ɺΫϥεΛϩʔυ͢Δ • ࠷ۙͷPHPϓϩδΣΫτͩͱී௨ʹ࢖ΘΕͯ ͍Δ

Slide 45

Slide 45 text

ศར͚ͩͲ…ʁ

Slide 46

Slide 46 text

autoloadͱ͸ • ಛఆͷؔ਺Λ࣮ߦͯ͠ϑΝΠϧΛ require_once͠ɺΫϥεΛϩʔυ͢Δ • ࠷ۙͷPHPϓϩδΣΫτͩͱී௨ʹ࢖ΘΕͯ ͍Δ

Slide 47

Slide 47 text

ίʔυΛ࣮ߦ͠ͳ͍ͱݴͬͨͳɻ ͋Ε͸ӕͩɻ • PHPStan͸Ұ෦ίʔυΛ࣮ߦ͢Δ • "੩త"ͪΌ͏Μ͔ʔ͍ • Phan͸autoload͕ઃఆͰ͖ͳ͍͕ɺ੩తղੳ Ͱ͋Δ͜ͱʹ஧࣮

Slide 48

Slide 48 text

"࣮ߦ"͢ΔͷͰ • autoloadϑΝΠϧࣗମ͕exit͢Δͱphpstan΋ Ϋϥογϡ͢Δ • autoloadʹΑͬͯݺͼग़͞ΕͨϑΝΠϧ͸
 ࣮ߦ͞Εͯ͠·͏

Slide 49

Slide 49 text

PHPͷ੩తղੳͮ͠Β͍ͱ͜Ζ • ίϯύΠϧͱϥϯλΠϜͷڥք͕͸͖ͬΓ͠ͳ͍ ఆٛ ࣮ߦ ఆٛ ࣮ߦ ఆٛ ࣮ߦ ఆٛ ࣮ߦ autoload autoload autoload

Slide 50

Slide 50 text

৘੎ͷมԽ

Slide 51

Slide 51 text

"ϞμϯͳελΠϧ"ͷཱ֬ • autoload͕ී௨ɻcomposerͷඪ४ʹै͏ • ن໿ͱͯ͠PSR-1Λक͍ͬͯΔ͔ΒɺΫϥεఆ ٛʹ͸ఆٛҎ֎ͷ෭࡞༻͕ͳ͍͸ͣ

Slide 52

Slide 52 text

PHPStanͷཱͪҐஔ • Ϋϥεϩʔυ͚ͩϥϯλΠϜΛڐ͢ • "ϞμϯͳελΠϧʹ࠷దԽ" ఆٛ ࣮ ߦ autoload ఆٛ ࣮ ߦ ఆٛ ఆٛ autoload autoload

Slide 53

Slide 53 text

ಘΒΕͨ΋ͷ • ಋೖͷ͠қ͞ • ղੳͷߴ଎ੑ • গ͠ͷةݥੑ

Slide 54

Slide 54 text

ݸਓతҙݟ • 100%੩తʹؤுΔͷͰ͸ͳ͘ɺಈత΋ࠞͥΔ • PHPΒͯ͘͠ɺ͍͍མͱ͠ॴͷπʔϧ • ܕએݴͷه๏ͷॆ࣮΍ɺPSR-1ͳͲͷจԽ͕Ͱ ͖͔ͨΒͦ͜ɺ࡞Εͨπʔϧ

Slide 55

Slide 55 text

ୈ4෦ ࣮ફɾܕ஫ऍ PHPStanʹΑΔܧଓత੩తղੳ

Slide 56

Slide 56 text

PHPStanͷجຊಈ࡞ • ίʔυʹॻ͍ͯ͋Δܕ஫ऍΛ΋ͱʹɺ͋Γ͑ ͳ͍ૢ࡞Λ͍ͯͨ͠ΒΤϥʔʹ͢Δ • ܕ஫ऍ͕ஸೡͩͱɺݕࠪ΋ஸೡʹͳΔ • ܕʹର͢Δ஌͕ࣝ͋Δͱ͸͔ͲΔ

Slide 57

Slide 57 text

ܕએݴͱPHPDoc • PHPͷܕ஫ऍ͸ࣗ༝౓͕௿͍ • ͳͷͰɺPHPDocΛࠞͥͯ࢖͏ • PHPStan͸ͲͪΒ΋ղऍͯ͘͠ΕΔ

Slide 58

Slide 58 text

PHP7ͷܕએݴ • int, float, bool, string, array, Ϋϥε/Πϯλʔϑ Σʔε໊, callable, iterable • ?Λઌ಄ʹ͚ͭΔ/σϑΥϧτҾ਺Λnullʹ͢Δ ͱnullable

Slide 59

Slide 59 text

εΧϥܕʹ஫ҙ • double͡Όͳͯ͘float • integer, boolean͡Όͳͯ͘int, bool • ؒҧ͑ΔͱΫϥε໊ͱͯ͠ղऍ͞ΕΔ

Slide 60

Slide 60 text

PHPDoc • PHPެࣜͷػೳͰ͸ͳ͍ ͕ɺ΄΅ඪ४͕͋Δ • docBlock (/** ~ */) Λؔ਺ ͷ௚લʹهೖ

Slide 61

Slide 61 text

PHPDocͷߏจ • @param ܕ໊ $ม਺໊ આ໌ • εϖʔε۠੾ΓͳͷͰɺܕ໊ʹεϖʔεΛೖΕ ͯ͸͍͚ͳ͍ • ܕ͸লུෆՄ • JavaDocͷͭ΋ΓͰॻ͘ͱจ๏Τϥʔ

Slide 62

Slide 62 text

PHPDocಠࣗͷܕه๏ • \DateTime[] ͳͲͷܕݻఆ഑ྻ • string|null ͳͲͷunion෩ه๏ • true/false ΋ॻ͚Δ • @return $this • ϝιουνΣʔϯͷ໌ࣔ

Slide 63

Slide 63 text

PHPStanͰunionͷݕࠪ →hoge() should return string but returns bool|string.

Slide 64

Slide 64 text

PHPStanͰunionͷݕࠪ →hoge() should return string but returns false|string.

Slide 65

Slide 65 text

PHPStanͰunionͷݕࠪ ݁ߏ͔͍͜͠ʂ

Slide 66

Slide 66 text

PHPStanͰnullableͷݕࠪ • ?string ΍ string|null ͲͪΒ΋ೝࣝ͢Δ • ifจͰݕ͔ࠪͯ͠Βࢀর͢Ε͹ݕࠪOK

Slide 67

Slide 67 text

ݱঢ়Ͱ͖ͳ͍͜ͱ • ܧঝؔ܎Λ͏·͘ѻ͑ͳ͍͜ͱ͕͋Δ
 (൓มɾڞม) • هड़Ͱ͖ͳ͍ܕ͕͍ͬͺ͍ • ࿈૝഑ྻͷৄ͍͠هड़

Slide 68

Slide 68 text

Ϧείϑͷஔ׵ݪଇ(LSP) • ܕΛ೿ੜͨ͠ͱ͖ɺ
 ΋ͱͷೳྗ͕ݮͬͨΒμϝ • ຬͨͯ͠Ε͹ϝιουΛ
 ্ॻ͖ͯ͠΋OK جఈ

Slide 69

Slide 69 text

LSPతʹOKͳ্ॻ͖ • ϝιουΛΦʔόʔϥΠυͨ͠ͱ͖ɺPHPެ ࣜͰ͸ܕએݴΛมߋͰ͖ͳ͍ • 7.2Ͱܕফڈ͚ͩڐՄ͞Εͨ • PHPDoc + PHPStanͩͱνΣοΫ͞Εͳ͍

Slide 70

Slide 70 text

هड़ํ๏͕ͳ͍ܕͷྫ • ArrayObject • function (int): int • [int, float] (࿈૝഑ྻͰ)

Slide 71

Slide 71 text

ΫϥεͰؤுΕͳ͘΋ͳ͍ Ҏ߱͸IntArrayͰܕΛهड़ ࣮૷ʹ΋IntArrayΛ࢖͏

Slide 72

Slide 72 text

ΫϥεͰؤுΕͳ͘΋ͳ͍ callableͰ͸ͳ͘ ΠϯλʔϑΣʔε ΫϩʔδϟͰ͸ͳ͘ ແ໊Ϋϥε

Slide 73

Slide 73 text

ʘ໘౗͍͘͞ʗ

Slide 74

Slide 74 text

ʘHackͳΒͰ͖Δͷʹʂʗ

Slide 75

Slide 75 text

ແཧʹؤுΔඞཁ͸ͳ͍

Slide 76

Slide 76 text

ςετ͢Ε͹͍͍ΜͰ͢ • PHP͸ಈతܕ෇͖ݴޠ • ࠔͬͨΒܕ஫ऍΛফͯ͠mixedʹ໭Ζ͏ • ෆ҆ͳΒϢχοτςετ

Slide 77

Slide 77 text

·ͱΊ • PHP΋੩తղੳ͕͠΍͘͢ͳͬͨ • staticํ໘Λॆ࣮ͤ͞Ε͹ɺയવͱͨ͠ෆ͕҆ ݮΒͤΔ • ಈతͱ੩తͷΦΠγΠͱ͜ΖΛ࢖͍ͬͯ͜͏

Slide 78

Slide 78 text

ࢀߟจݙ • https://ja.wikipedia.org/wiki/ແݶϧʔϓ • PHPDocͷߏจ͸PSR-5͕ಡΈ΍͍͢
 https://github.com/php-fig/fig-standards/blob/ master/proposed/phpdoc.md • https://ja.wikipedia.org/wiki/ڞมੑͱ൓มੑ _(ܭࢉػՊֶ)