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

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

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

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

B989cc865d53d8e26fdadac99727113c?s=128

Satoshi Kawashima

March 31, 2019
Tweet

Transcript

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

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

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

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

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

  6. #VU

  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()]; } }
  8. ؂־׾־

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

  10.  ೴಺ઃܭ ίʔυ

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

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

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

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

  15. IUUQTQBDLBHJTUPSHQBDLBHFTOB[POPIJUPEFQFOEFODZBOBMZ[FS EFQFOEFODZBOBMZ[FS

  16. 1PXFSFECZ  1)14UBO

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

  18. 8IBUJT❣㰆꞊➟ 

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

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

  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()]; } }
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  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
  34. UZQFIJOUJOH OFXPCKFDU QVCMJDQSPQFSUZDPOTUBOU GFUDI SFUVSOWBMVFUZQF DBMMQVCMJDNFUIPE QIQEPD VTFUSBJU DBUDI FYUFOETJNQMFNFOUT

    UISPX ❣㰆꞊➟ֿ氦榟׌׾ب٤ذشؠت┉鼧 
  35. ❣㰆꞊➟؅鉮冪׊յ  %FQFOEFS %FQFOEFF %FQFOEFF %FQFOEFF %FQFOEFF %FQFOEFF

  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
  37. 僗⺸ءٚن׫㚺䬵  " & % $ # ' ( *

    ) ( , +
  38.  僗⺸ءٚن؅➘⮵מ✳ֹ ❣㰆꞊➟סٜ٭ٜزؘشؠ  ءٚن槆⥼ס榟䡗  䐠梪❣㰆ס吾⭳ 

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

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

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

  42. ❣㰆ٜ٭ٜס䧗㲊亠嫎  <?php 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'] ] ] ];
  43. <?php 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'] ] ] ]; ❣㰆ٜ٭ٜס䧗㲊亠嫎  ٜ٭ٜ⺲
  44. <?php 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'] ] ] ]; ❣㰆ٜ٭ٜס䧗㲊亠嫎  ؤ٤َ٭ؾ٤عס㲊紶 ⺲⯥狜ꝴך䧗㲊
  45. <?php 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❣㰆׊י׵荁ַؤ٤َ٭ؾ٤ع
  46. ٜ٭ٜ鷿⹚סزؘشؠ  $*ךزؘشؠ⺎耆

  47. <?php 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'] ] ] ]; ❣㰆ٜ٭ٜס䧗㲊亠嫎  ׆סٜ٭ٜنٜؒؕ舅⛮ֿյ אסَٛةعٛמֽׄ׾ 錃銶䧗ꄠס辐伺כ׊י䣽ֻ׾
  48. QIQEPDמ׻׾❣㰆ٜ٭ٜס䧗㲊  <?php declare(strict_types=1); namespace Acme\Domain\ValueObjects; /** * @canOnlyUsedBy \Acme\Domain\Entities\User

    * @canOnlyUsedBy \Acme\Domain\Repositories\UserRepository */ class UserName { // ... } !DBO0OMZ6TFE#Z ך׆סؠٚتמ❣㰆׊י׵荁ַؠٚت؅꡾㲊⴫
  49. QIQEPDמ׻׾❣㰆ٜ٭ٜס䧗㲊  $*ךزؘشؠ⺎耆

  50. <?php $controllerDefine = ['\App\\', '!\App\Providers\\']; $applicationDefine = ['\Acme\Application\\']; $domainDefine =

    ['\Acme\Domain\\']; return [ '<error>Facadeܯ࡯ͩɺखΛ্͛Ζʂʂ </error>' => [ '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閛㴔׵ך׀׾ 
  51. 'BDBEF閛㴔׵ך׀׾ 

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

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

    ) ( , +
  54. 䐠梪❣㰆ס吾⭳ 

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

  56. 5BLFBHPPE TPGUXBSFEFTJHOMJGF 

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

  58. 8F˖SF)JSJOH 