Upgrade to PRO for Only $50/Year—Limited-Time Offer! 🔥

単方向依存を実現する静的解析ライブラリのご紹介 / 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. ゖ❣㰆׊יַ׾ؠٚت؅⪒י䧸ׅ׻  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()]; } }
  2. ❆ֻף׆סؠٚتס㕙⺬  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()]; } }
  3. ❆ֻף׆סؠٚتס㕙⺬  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
  4. ❆ֻף׆סؠٚتס㕙⺬  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
  5. ❆ֻף׆סؠٚتס㕙⺬  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
  6. ❆ֻף׆סؠٚتס㕙⺬  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
  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()]; } } QVCMJDQSPQFSUZGFUDI
  8. ❆ֻף׆סؠٚتס㕙⺬  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
  9. ❆ֻף׆סؠٚتס㕙⺬  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
  10. ❆ֻף׆סؠٚتס㕙⺬  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
  11. ❆ֻף׆סؠٚتס㕙⺬  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
  12. ❆ֻף׆סؠٚتס㕙⺬  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
  13. ❆ֻף׆סؠٚتס㕙⺬  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
  14. ❆ֻף׆סؠٚتס㕙⺬  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
  15. ⪒ؠٚتס❣㰆꞊➟؅꥗״յ  %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
  16. ❣㰆ٜ٭ٜס䧗㲊亠嫎  <?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'] ] ] ];
  17. <?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'] ] ] ]; ❣㰆ٜ٭ٜס䧗㲊亠嫎  ٜ٭ٜ⺲
  18. <?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'] ] ] ]; ❣㰆ٜ٭ٜס䧗㲊亠嫎  ؤ٤َ٭ؾ٤عס㲊紶 ⺲⯥狜ꝴך䧗㲊
  19. <?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❣㰆׊י׵荁ַؤ٤َ٭ؾ٤ع
  20. <?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'] ] ] ]; ❣㰆ٜ٭ٜס䧗㲊亠嫎  ׆סٜ٭ٜنٜؒؕ舅⛮ֿյ אסَٛةعٛמֽׄ׾ 錃銶䧗ꄠס辐伺כ׊י䣽ֻ׾
  21. QIQEPDמ׻׾❣㰆ٜ٭ٜס䧗㲊  <?php declare(strict_types=1); namespace Acme\Domain\ValueObjects; /** * @canOnlyUsedBy \Acme\Domain\Entities\User

    * @canOnlyUsedBy \Acme\Domain\Repositories\UserRepository */ class UserName { // ... } !DBO0OMZ6TFE#Z ך׆סؠٚتמ❣㰆׊י׵荁ַؠٚت؅꡾㲊⴫
  22. <?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閛㴔׵ך׀׾ 