🙆

[PHP]コードからmermaidjsのクラス図を自動生成するツールを作りました

2022/08/21に公開

概要

PHPのコードからmermaidjsのクラス図を自動生成するツールを作ってみました。
https://github.com/tasuku43/php-mermaid-class-diagram

僕はずっとPlantUML派だったのですが、ここ最近では色々なサービスでサポートされるようになり、「PlantUMLからMermaidに改宗するかー」という方も少なくないのではないでしょうか。
MermaidはQiitaやZennなどの記事投稿サイトで利用できるようになったのも嬉しいですし、なんといってもGitHubでサポートされるようになったのでPRでのコミュニケーションにも使えるようになったのは超嬉しいです。

現状はInheritance(継承)、Realization(実現)、Composition(コンポジション)の関係性を描画できるようにしており、クラス内部の詳細(プロパティ、メソッドの情報など)は省略しています。
個人的には上記くらいの「ざっくりとしたクラスの関係性をパッと見えるようにしたいなー」というモチベーションで作ったので今のところ機能の拡張は考えてないのですが、もし需要があってIssueなどがたった場合は対応しようと思ってます。

インストール方法

packagistに公開しているので、以下のコマンドでinstallできます。

composer require --dev tasuku43/mermaid-class-diagram

使い方

以下のようなシンプルなプロジェクトで利用した場合を例に、コマンドの実行結果を紹介します。

$ tree
.
├── composer.json
├── composer.lock
├── src
│   ├── SomeAbstractClass.php
│   ├── SomeClassA.php
│   ├── SomeClassB.php
│   ├── SomeClassC.php
│   └── SomeInterface.php
└── vendor
class SomeClassA extends SomeAbstractClass
{
    private SomeClassB $someClassB;

    public function __construct(private SomeClassC $someClassC)
    {
    }
}

class SomeClassB
{
}

class SomeClassC
{
}

abstract class SomeAbstractClass implements SomeInterface
{
}

interface SomeInterface
{
}

ディレクトリを指定して実行した場合

ディレクトリ配下のファイルが全て対象になります。

$ vendor/bin/mermaid-class-diagram generate --path src
classDiagram
    class SomeClassC {
    }
    class SomeClassB {
    }
    class SomeAbstractClass {
        <<abstruct>>
    }
    class SomeClassA {
    }
    class SomeInterface {
        <<interface>>
    }

    SomeAbstractClass ..|> SomeInterface: realization
    SomeClassA --|> SomeAbstractClass: inheritance
    SomeClassA *-- SomeClassB: composition
    SomeClassA *-- SomeClassC: composition

特定ファイルを指定して実行した場合

ファイル単体で指定する事も可能です。この場合は継承クラスなどの情報は少なくなります。(といっても現状の実装ではAbstract classInterfaceかくらいしか分からないので、あまり差はなさそう)

$ vendor/bin/mermaid-class-diagram generate --path src/SomeClassA.php
classDiagram
    class SomeClassA {
    }

    SomeClassA --|> SomeAbstractClass: inheritance
    SomeClassA *-- SomeClassB: composition
    SomeClassA *-- SomeClassC: composition

Discussion