Symfony
Symfony4
SymfonyDay 23

Symfony4のsrcディレクトリを若干変更してみた

Symfony4からはbundle-lessアプリケーションということで、ディレクトリ構造が変わりました。
今まではsrc/AppBundleが標準で用意されましたが、それもなくなりました。

composer create-projectでsymfonyのプロジェクトを作成すると、Symfony4のsrcディレクトリ以下はこんな感じです。

src
├── Controller
└── Kernel.php

しかし、このディレクトリ構成だと複雑でモノリシックなアプリケーションを作る場合につらい・・・。
せめてこんな感じのディレクトリ構成にしたい

src
└── App
    ├── Controller
    └── Kernel.php

とうことで、ディレクトリ構成の変更してみたいと思います。

1. autoloadの設定を変更する

composer.jsonにautoloadの設定が記述されています。

    "autoload": {
        "psr-4": {
            "App\\": "src/"
        }
    },

これを

    "autoload": {
        "psr-4": {
            "App\\": "src/App/"
        }
    },

2. config/services.yamlの設定を変更する

autowiringのディレクトリの指定を変更します。

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/*'
        exclude: '../src/{Entity,Migrations,Tests}'

    # controllers are imported separately to make sure services can be injected
    # as action arguments even if you don't extend any base controller class
    App\Controller\:
        resource: '../src/Controller'
        tags: ['controller.service_arguments']

これを

    # makes classes in src/ available to be used as services
    # this creates a service per class whose id is the fully-qualified class name
    App\:
        resource: '../src/App/*'
        exclude: '../src/App/{Entity,Migrations,Tests}'

    # controllers are imported separately to make sure services can be injected
    # as action arguments even if you don't extend any base controller class
    App\Controller\:
        resource: '../src/App/Controller'
        tags: ['controller.service_arguments']

doctrineを利用している場合はconfig/doctrine.yamlの設定も変更する

Doctrineを利用する場合はmappingsの設定も変更する必要があります。

    orm:
        auto_generate_proxy_classes: '%kernel.debug%'
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true
        mappings:
            App:
                is_bundle: false
                type: annotation
                dir: '%kernel.project_dir%/src/Entity'
                prefix: 'AppEntity'
                alias: App

これを以下のようにします。

    orm:
        auto_generate_proxy_classes: '%kernel.debug%'
        naming_strategy: doctrine.orm.naming_strategy.underscore
        auto_mapping: true
        mappings:
            App:
                is_bundle: false
                type: annotation
                dir: '%kernel.project_dir%/src/App/Entity'
                prefix: 'AppEntity'
                alias: App

ちなみにorm-packをrequireするとconfig/routes/annotations.yamlも生成されるので設定を変更します。

controllers:
    resource: ../../src/Controller/
    type: annotation

これを

controllers:
    resource: ../../src/App/Controller/
    type: annotation

最後に

簡単に標準のディレクトリ構成から変更することが可能です。
若干Symfony Recipesの恩恵を受けづらくなりますが、まあディレクトリ名を変える程度のなのでありなのかなーと思います。

ちなみに僕が今進めているプロジェクトは

.
├── App
│   ├── Command
│   ├── Controller
│   ├── Kernel.php
│   ├── Migrations
│   ├── Repository
│   └── Security
└── Domain
    ├── Context1
    ├── Context2
    └── Context3

みたいな感じにディレクトリを分けています。

フレームワークの機能を分離する という理由でApp,Domainとディレクトリを分けています。
Symfonyの機能を利用する場合は、Appディレクトリ側に実装するというルールにしています。

ということで、自分なりのディレクトリ構成を作ってみるのも良いのかもしれません。