Upgrade to Pro — share decks privately, control downloads, hide ads and more …

単方向依存を実現する静的解析ライブラリのご紹介 / Analyze PHP Dependencies

単方向依存を実現する静的解析ライブラリのご紹介 / Analyze PHP Dependencies

クリーンアーキテクチャや独立したコアレイヤパターンなどのアーキテクチャ設計の広まりや、PHPがstaticに構造を持ち始めた時代を背景に、PHPの依存関係を静的解析するライブラリを作りましたのでご紹介しました。

是非使ってみてください!
https://packagist.org/packages/nazonohito51/dependency-analyzer

Satoshi Kawashima

March 31, 2019
Tweet

More Decks by Satoshi Kawashima

Other Decks in Programming

Transcript

  1. 1)1FS,BJHJ
    ⶡ亠⺸❣㰆؅㲔杯׌׾
    ꪐ氳鉮冪ٚؕهٚٛסׇ磆☭

    View Slide


  2. #"4&1SPEVDU%JWJTJPOմ䃷㼖䜔
    !OB[POPIJUP
    

    View Slide

  3. -BZFSFE"SDIJUFDUVSF
    %FQFOEFODZ*OWFSTJPO
    1SJODJQMF
    $MFBO"SDIJUFDUVSF

    View Slide

  4. ಠཱͨ͠ίΞϨΠϠύλʔϯ΋͋Δͧʂ
    IUUQTCMPHTIJOYDPNFOUSZJOEFQFOEFOUDPSFMBZFSQBUUFSO

    View Slide

  5. ؠٚتס❣㰆畘杼
    ע׋״ױ׊ג

    View Slide

  6. #VU

    View Slide

  7. ゖ❣㰆׊יַ׾ؠٚت؅⪒י䧸ׅ׻

    class SomeClass extends ParentClass implements SomeInterface
    {
    use SomeTrait;
    private $someClass1;
    public function __construct()
    {
    $this->someClass1 = new SomeClass1(SomeClass1::STATUS_OK);
    }
    public function someMethod(SomeClass1 $someClass1): SomeClass3
    {
    try {
    $unknownClass = $someClass1->someMethod1($this->someClass1->property);
    if (!$unknownClass instanceof SomeClass2) {
    throw new SomeException();
    }
    return $unknownClass->getSomeClass3();
    } catch (SomeException $e) {
    // TODO: error handling
    }
    }
    /**
    * @return SomeClass2[]
    */
    public function returnValueTypeByPhpDoc(): array
    {
    return [new SomeClass2(), new SomeClass2()];
    }
    }

    View Slide

  8. ؂־׾־

    View Slide

  9. 䡘չ☔걉ֿ
    خنعؘؗؓס啶鵰؅
    䨿ֻ׾׆כעꦘ׊ַ

    View Slide

  10. 
    ೴಺ઃܭ
    ίʔυ

    View Slide

  11. 
    ೴಺ઃܭ
    ίʔυ
    1)1TZOUBY
    QIQEPD
    FUD

    View Slide

  12. 鲣䇗ס1)1ע
    ꪐ氳מ
    啶鵰؅䧏ח׻ֹמםזי׀ג
    TUBUJD

    View Slide

  13. ☪׆א1)1خنعؘؗؓס
    ꪐ氳啶鵰מ泘؅⺸ׄ׾侇

    View Slide

  14. خنعؘؗؓס釤ֻ׾⴫
    
    ӳӳ

    View Slide

  15. IUUQTQBDLBHJTUPSHQBDLBHFTOB[POPIJUPEFQFOEFODZBOBMZ[FS
    EFQFOEFODZBOBMZ[FS

    View Slide

  16. 1PXFSFECZ
    
    1)14UBO

    View Slide

  17. ؠٚتס❣㰆꞊➟؅
    鉮冪׌׾ٚؕهٚٛ
    

    View Slide

  18. 8IBUJT❣㰆꞊➟
    

    View Slide

  19. ؕ٤ذ٭نؘ٭تֿ㚺催׈׿ג㕙⺬מ
    䏅ꮶֿ氦榟׌׾꞊➟
    

    View Slide

  20. ؕ٤ذ٭نؘ٭ت؅湳זיַ׾
    ❣㰆ֵֿ׾
    

    View Slide

  21. ❆ֻף׆סؠٚتס㕙⺬
    
    class SomeClass extends ParentClass implements SomeInterface
    {
    use SomeTrait;
    private $someClass1;
    public function __construct()
    {
    $this->someClass1 = new SomeClass1(SomeClass1::STATUS_OK);
    }
    public function someMethod(SomeClass1 $someClass1): SomeClass3
    {
    try {
    $unknownClass = $someClass1->someMethod1($this->someClass1->property);
    if (!$unknownClass instanceof SomeClass2) {
    throw new SomeException();
    }
    return $unknownClass->getSomeClass3();
    } catch (SomeException $e) {
    // TODO: error handling
    }
    }
    /**
    * @return SomeClass2[]
    */
    public function returnValueTypeByPhpDoc(): array
    {
    return [new SomeClass2(), new SomeClass2()];
    }
    }

    View Slide

  22. ❆ֻף׆סؠٚتס㕙⺬
    
    class SomeClass extends ParentClass implements SomeInterface
    {
    use SomeTrait;
    private $someClass1;
    public function __construct()
    {
    $this->someClass1 = new SomeClass1(SomeClass1::STATUS_OK);
    }
    public function someMethod(SomeClass1 $someClass1): SomeClass3
    {
    try {
    $unknownClass = $someClass1->someMethod1($this->someClass1->property);
    if (!$unknownClass instanceof SomeClass2) {
    throw new SomeException();
    }
    return $unknownClass->getSomeClass3();
    } catch (SomeException $e) {
    // TODO: error handling
    }
    }
    /**
    * @return SomeClass2[]
    */
    public function returnValueTypeByPhpDoc(): array
    {
    return [new SomeClass2(), new SomeClass2()];
    }
    }
    UZQFIJOUJOH

    View Slide

  23. ❆ֻף׆סؠٚتס㕙⺬
    
    class SomeClass extends ParentClass implements SomeInterface
    {
    use SomeTrait;
    private $someClass1;
    public function __construct()
    {
    $this->someClass1 = new SomeClass1(SomeClass1::STATUS_OK);
    }
    public function someMethod(SomeClass1 $someClass1): SomeClass3
    {
    try {
    $unknownClass = $someClass1->someMethod1($this->someClass1->property);
    if (!$unknownClass instanceof SomeClass2) {
    throw new SomeException();
    }
    return $unknownClass->getSomeClass3();
    } catch (SomeException $e) {
    // TODO: error handling
    }
    }
    /**
    * @return SomeClass2[]
    */
    public function returnValueTypeByPhpDoc(): array
    {
    return [new SomeClass2(), new SomeClass2()];
    }
    }
    SFUVSOWBMVFUZQF

    View Slide

  24. ❆ֻף׆סؠٚتס㕙⺬
    
    class SomeClass extends ParentClass implements SomeInterface
    {
    use SomeTrait;
    private $someClass1;
    public function __construct()
    {
    $this->someClass1 = new SomeClass1(SomeClass1::STATUS_OK);
    }
    public function someMethod(SomeClass1 $someClass1): SomeClass3
    {
    try {
    $unknownClass = $someClass1->someMethod1($this->someClass1->property);
    if (!$unknownClass instanceof SomeClass2) {
    throw new SomeException();
    }
    return $unknownClass->getSomeClass3();
    } catch (SomeException $e) {
    // TODO: error handling
    }
    }
    /**
    * @return SomeClass2[]
    */
    public function returnValueTypeByPhpDoc(): array
    {
    return [new SomeClass2(), new SomeClass2()];
    }
    }
    OFXPCKFDU

    View Slide

  25. ❆ֻף׆סؠٚتס㕙⺬
    
    class SomeClass extends ParentClass implements SomeInterface
    {
    use SomeTrait;
    private $someClass1;
    public function __construct()
    {
    $this->someClass1 = new SomeClass1(SomeClass1::STATUS_OK);
    }
    public function someMethod(SomeClass1 $someClass1): SomeClass3
    {
    try {
    $unknownClass = $someClass1->someMethod1($this->someClass1->property);
    if (!$unknownClass instanceof SomeClass2) {
    throw new SomeException();
    }
    return $unknownClass->getSomeClass3();
    } catch (SomeException $e) {
    // TODO: error handling
    }
    }
    /**
    * @return SomeClass2[]
    */
    public function returnValueTypeByPhpDoc(): array
    {
    return [new SomeClass2(), new SomeClass2()];
    }
    }
    DBMMQVCMJDNFUIPE

    View Slide

  26. ❆ֻף׆סؠٚتס㕙⺬
    
    class SomeClass extends ParentClass implements SomeInterface
    {
    use SomeTrait;
    private $someClass1;
    public function __construct()
    {
    $this->someClass1 = new SomeClass1(SomeClass1::STATUS_OK);
    }
    public function someMethod(SomeClass1 $someClass1): SomeClass3
    {
    try {
    $unknownClass = $someClass1->someMethod1($this->someClass1->property);
    if (!$unknownClass instanceof SomeClass2) {
    throw new SomeException();
    }
    return $unknownClass->getSomeClass3();
    } catch (SomeException $e) {
    // TODO: error handling
    }
    }
    /**
    * @return SomeClass2[]
    */
    public function returnValueTypeByPhpDoc(): array
    {
    return [new SomeClass2(), new SomeClass2()];
    }
    }
    QVCMJDQSPQFSUZGFUDI

    View Slide

  27. ❆ֻף׆סؠٚتס㕙⺬
    
    class SomeClass extends ParentClass implements SomeInterface
    {
    use SomeTrait;
    private $someClass1;
    public function __construct()
    {
    $this->someClass1 = new SomeClass1(SomeClass1::STATUS_OK);
    }
    public function someMethod(SomeClass1 $someClass1): SomeClass3
    {
    try {
    $unknownClass = $someClass1->someMethod1($this->someClass1->property);
    if (!$unknownClass instanceof SomeClass2) {
    throw new SomeException();
    }
    return $unknownClass->getSomeClass3();
    } catch (SomeException $e) {
    // TODO: error handling
    }
    }
    /**
    * @return SomeClass2[]
    */
    public function returnValueTypeByPhpDoc(): array
    {
    return [new SomeClass2(), new SomeClass2()];
    }
    }
    QVCMJDDPOTUBOUGFUDI

    View Slide

  28. ❆ֻף׆סؠٚتס㕙⺬
    
    class SomeClass extends ParentClass implements SomeInterface
    {
    use SomeTrait;
    private $someClass1;
    public function __construct()
    {
    $this->someClass1 = new SomeClass1(SomeClass1::STATUS_OK);
    }
    public function someMethod(SomeClass1 $someClass1): SomeClass3
    {
    try {
    $unknownClass = $someClass1->someMethod1($this->someClass1->property);
    if (!$unknownClass instanceof SomeClass2) {
    throw new SomeException();
    }
    return $unknownClass->getSomeClass3();
    } catch (SomeException $e) {
    // TODO: error handling
    }
    }
    /**
    * @return SomeClass2[]
    */
    public function returnValueTypeByPhpDoc(): array
    {
    return [new SomeClass2(), new SomeClass2()];
    }
    }
    QIQEPD

    View Slide

  29. ❆ֻף׆סؠٚتס㕙⺬
    
    class SomeClass extends ParentClass implements SomeInterface
    {
    use SomeTrait;
    private $someClass1;
    public function __construct()
    {
    $this->someClass1 = new SomeClass1(SomeClass1::STATUS_OK);
    }
    public function someMethod(SomeClass1 $someClass1): SomeClass3
    {
    try {
    $unknownClass = $someClass1->someMethod1($this->someClass1->property);
    if (!$unknownClass instanceof SomeClass2) {
    throw new SomeException();
    }
    return $unknownClass->getSomeClass3();
    } catch (SomeException $e) {
    // TODO: error handling
    }
    }
    /**
    * @return SomeClass2[]
    */
    public function returnValueTypeByPhpDoc(): array
    {
    return [new SomeClass2(), new SomeClass2()];
    }
    }
    FYUFOET

    View Slide

  30. ❆ֻף׆סؠٚتס㕙⺬
    
    class SomeClass extends ParentClass implements SomeInterface
    {
    use SomeTrait;
    private $someClass1;
    public function __construct()
    {
    $this->someClass1 = new SomeClass1(SomeClass1::STATUS_OK);
    }
    public function someMethod(SomeClass1 $someClass1): SomeClass3
    {
    try {
    $unknownClass = $someClass1->someMethod1($this->someClass1->property);
    if (!$unknownClass instanceof SomeClass2) {
    throw new SomeException();
    }
    return $unknownClass->getSomeClass3();
    } catch (SomeException $e) {
    // TODO: error handling
    }
    }
    /**
    * @return SomeClass2[]
    */
    public function returnValueTypeByPhpDoc(): array
    {
    return [new SomeClass2(), new SomeClass2()];
    }
    }
    JNQMFNFOUT

    View Slide

  31. ❆ֻף׆סؠٚتס㕙⺬
    
    class SomeClass extends ParentClass implements SomeInterface
    {
    use SomeTrait;
    private $someClass1;
    public function __construct()
    {
    $this->someClass1 = new SomeClass1(SomeClass1::STATUS_OK);
    }
    public function someMethod(SomeClass1 $someClass1): SomeClass3
    {
    try {
    $unknownClass = $someClass1->someMethod1($this->someClass1->property);
    if (!$unknownClass instanceof SomeClass2) {
    throw new SomeException();
    }
    return $unknownClass->getSomeClass3();
    } catch (SomeException $e) {
    // TODO: error handling
    }
    }
    /**
    * @return SomeClass2[]
    */
    public function returnValueTypeByPhpDoc(): array
    {
    return [new SomeClass2(), new SomeClass2()];
    }
    }
    VTFUSBJU

    View Slide

  32. ❆ֻף׆סؠٚتס㕙⺬
    
    class SomeClass extends ParentClass implements SomeInterface
    {
    use SomeTrait;
    private $someClass1;
    public function __construct()
    {
    $this->someClass1 = new SomeClass1(SomeClass1::STATUS_OK);
    }
    public function someMethod(SomeClass1 $someClass1): SomeClass3
    {
    try {
    $unknownClass = $someClass1->someMethod1($this->someClass1->property);
    if (!$unknownClass instanceof SomeClass2) {
    throw new SomeException();
    }
    return $unknownClass->getSomeClass3();
    } catch (SomeException $e) {
    // TODO: error handling
    }
    }
    /**
    * @return SomeClass2[]
    */
    public function returnValueTypeByPhpDoc(): array
    {
    return [new SomeClass2(), new SomeClass2()];
    }
    }
    UISPX

    View Slide

  33. ❆ֻף׆סؠٚتס㕙⺬
    
    class SomeClass extends ParentClass implements SomeInterface
    {
    use SomeTrait;
    private $someClass1;
    public function __construct()
    {
    $this->someClass1 = new SomeClass1(SomeClass1::STATUS_OK);
    }
    public function someMethod(SomeClass1 $someClass1): SomeClass3
    {
    try {
    $unknownClass = $someClass1->someMethod1($this->someClass1->property);
    if (!$unknownClass instanceof SomeClass2) {
    throw new SomeException();
    }
    return $unknownClass->getSomeClass3();
    } catch (SomeException $e) {
    // TODO: error handling
    }
    }
    /**
    * @return SomeClass2[]
    */
    public function returnValueTypeByPhpDoc(): array
    {
    return [new SomeClass2(), new SomeClass2()];
    }
    }
    DBUDI

    View Slide

  34. UZQFIJOUJOH
    OFXPCKFDU
    QVCMJDQSPQFSUZDPOTUBOU
    GFUDI
    SFUVSOWBMVFUZQF
    DBMMQVCMJDNFUIPE
    QIQEPD
    VTFUSBJU
    DBUDI
    FYUFOETJNQMFNFOUT
    UISPX
    ❣㰆꞊➟ֿ氦榟׌׾ب٤ذشؠت┉鼧
    

    View Slide

  35. ❣㰆꞊➟؅鉮冪׊յ
    
    %FQFOEFS
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF

    View Slide

  36. ⪒ؠٚتס❣㰆꞊➟؅꥗״յ
    
    %FQFOEFS
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFS
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFS
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFS
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFS
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFS
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF
    %FQFOEFF

    View Slide

  37. 僗⺸ءٚن׫㚺䬵
    
    "
    &
    %
    $
    #
    '
    (
    *
    )
    (
    ,
    +

    View Slide

  38. 
    僗⺸ءٚن؅➘⮵מ✳ֹ
    ❣㰆꞊➟סٜ٭ٜزؘشؠ

    ءٚن槆⥼ס榟䡗

    䐠梪❣㰆ס吾⭳

    View Slide

  39. ءٚن槆⥼؅榟䡗
    
    杯㏇עQVNMסײ㵚䑴

    View Slide

  40. ءٚن槆⥼؅榟䡗
    
    ך־׌ׁ׾㕙⺬ע؛وب٘٤䧗㲊ךױכ
    ״׾׆כ׵⭳全׾
    OBNFTQBDFךױכ״׾
    ؙ٤عٛמױכ״׾

    View Slide

  41. ❣㰆꞊➟סٜ٭ٜزؘشؠ
    
    ز٭ّך婊״ג❣㰆ٜ٭ٜסزؘشؠֿ
    ך׀׾
    &OUFSQSJTF#VTJOFTT3VMFT
    "QQMJDBUJPO#VTJOFTT3VMFT
    *OUFSGBDF"EBQUFST
    'SBNFXPSLT%SJWFST

    View Slide

  42. ❣㰆ٜ٭ٜס䧗㲊亠嫎
    
    return [
    'Layer dependency rule' => [
    'controller_layer' => [
    'define' => ['\App\\', '!\App\Providers\\'],
    ],
    'application_layer' => [
    'define' => ['\Acme\Application\\'],
    'depender' => ['controller_layer'],
    ],
    'domain_layer' => [
    'define' => ['\Acme\Domain\\'],
    'depender' => ['application_layer']
    ]
    ]
    ];

    View Slide

  43. return [
    'Layer dependency rule' => [
    'controller_layer' => [
    'define' => ['\App\\', '!\App\Providers\\'],
    ],
    'application_layer' => [
    'define' => ['\Acme\Application\\'],
    'depender' => ['controller_layer'],
    ],
    'domain_layer' => [
    'define' => ['\Acme\Domain\\'],
    'depender' => ['application_layer']
    ]
    ]
    ];
    ❣㰆ٜ٭ٜס䧗㲊亠嫎
    
    ٜ٭ٜ⺲

    View Slide

  44. return [
    'Layer dependency rule' => [
    'controller_layer' => [
    'define' => ['\App\\', '!\App\Providers\\'],
    ],
    'application_layer' => [
    'define' => ['\Acme\Application\\'],
    'depender' => ['controller_layer'],
    ],
    'domain_layer' => [
    'define' => ['\Acme\Domain\\'],
    'depender' => ['application_layer']
    ]
    ]
    ];
    ❣㰆ٜ٭ٜס䧗㲊亠嫎
    
    ؤ٤َ٭ؾ٤عס㲊紶
    ⺲⯥狜ꝴך䧗㲊

    View Slide

  45. return [
    'Layer dependency rule' => [
    'controller_layer' => [
    'define' => ['\App\\', '!\App\Providers\\'],
    ],
    'application_layer' => [
    'define' => ['\Acme\Application\\'],
    'depender' => ['controller_layer'],
    ],
    'domain_layer' => [
    'define' => ['\Acme\Domain\\'],
    'depender' => ['application_layer']
    ]
    ]
    ];
    ❣㰆ٜ٭ٜס䧗㲊亠嫎
    
    ؤ٤َ٭ؾ٤عס❣㰆ٜ٭ٜס㲊紶
    EFQFOEFS❣㰆׈׿י׵荁ַؤ٤َ٭ؾ٤ع
    EQFFOEFF❣㰆׊י׵荁ַؤ٤َ٭ؾ٤ع

    View Slide

  46. ٜ٭ٜ鷿⹚סزؘشؠ
    
    $*ךزؘشؠ⺎耆

    View Slide

  47. return [
    'Layer dependency rule' => [
    'controller_layer' => [
    'define' => ['\App\\', '!\App\Providers\\'],
    ],
    'application_layer' => [
    'define' => ['\Acme\Application\\'],
    'depender' => ['controller_layer'],
    ],
    'domain_layer' => [
    'define' => ['\Acme\Domain\\'],
    'depender' => ['application_layer']
    ]
    ]
    ];
    ❣㰆ٜ٭ٜס䧗㲊亠嫎
    
    ׆סٜ٭ٜنٜؒؕ舅⛮ֿյ
    אסَٛةعٛמֽׄ׾
    錃銶䧗ꄠס辐伺כ׊י䣽ֻ׾

    View Slide

  48. QIQEPDמ׻׾❣㰆ٜ٭ٜס䧗㲊
    
    declare(strict_types=1);
    namespace Acme\Domain\ValueObjects;
    /**
    * @canOnlyUsedBy \Acme\Domain\Entities\User
    * @canOnlyUsedBy \Acme\Domain\Repositories\UserRepository
    */
    class UserName
    {
    // ...
    }
    !DBO0OMZ6TFE#Z
    ך׆סؠٚتמ❣㰆׊י׵荁ַؠٚت؅꡾㲊⴫

    View Slide

  49. QIQEPDמ׻׾❣㰆ٜ٭ٜס䧗㲊
    
    $*ךزؘشؠ⺎耆

    View Slide

  50. $controllerDefine = ['\App\\', '!\App\Providers\\'];
    $applicationDefine = ['\Acme\Application\\'];
    $domainDefine = ['\Acme\Domain\\'];
    return [
    'Facadeܯ࡯ͩɺखΛ্͛Ζʂʂ ' => [
    'Sanctuary' => [
    'define' => array_merge($controllerDefine, $applicationDefine, $domainDefine),
    'dependee' => ['!Facade']
    ],
    'Facade' => [
    'define' => [
    '\App','\Artisan','\Auth','\Blade','\Broadcast','\Bus','\Cache','\Config',
    '\Cookie','\Crypt','\DB','\Event','\File','\Gate','\Hash','\Lang','\Log',
    '\Mail','\Notification','\Password','\Queue','\Redirect','\Request','\Response',
    '\Route','\Schema','\Session','\Storage','\URL','\Validator','\View'
    ]
    ]
    ]
    ];
    'BDBEF閛㴔׵ך׀׾
    

    View Slide

  51. 'BDBEF閛㴔׵ך׀׾
    

    View Slide

  52. 䐠梪❣㰆ס吾⭳
    
    ˘ؤ٤َ٭ؾ٤عס❣㰆ءٚنמ䐠梪❣㰆ֵֿזיעם׼םַ˙
    $MFBO"SDIJUFDUVSF
    瑬珕ؤ٤َ٭ؾ٤عס磵⺬
    "DZDMJD%FQFOEFODJFT1SJODJQMF
    ꪜ䐠梪❣㰆꞊➟ס⸉⯞

    View Slide

  53. ⮆־׽ט׼ַ䐠梪❣㰆
    
    "
    &
    %
    $
    #
    '
    (
    *
    )
    (
    ,
    +

    View Slide

  54. 䐠梪❣㰆ס吾⭳
    

    View Slide

  55. IUUQTQBDLBHJTUPSHQBDLBHFTOB[POPIJUPEFQFOEFODZBOBMZ[FS
    佭ꪜ✳זיׂד׈ַ

    View Slide

  56. 5BLFBHPPE
    TPGUXBSFEFTJHOMJGF
    

    View Slide

  57. ׇ岲绱
    ֵ׽ֿכׇֹ׉ַױ׊ג
    

    View Slide

  58. 8F˖SF)JSJOH
    

    View Slide