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の設定が記述されています。

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

```

これを

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

```

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

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

```yaml
    # 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']
```

これを

```yaml
    # 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の設定も変更する必要があります。

```yaml
    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
```

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

```yaml
    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`も生成されるので設定を変更します。

```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ディレクトリ側に実装するというルールにしています。


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