Symfony4でTodoアプリを作って気づいた事

[Symfony Advent Calendar 2017](https://qiita.com/advent-calendar/2017/symfony) 2日目の記事です。
昨日の記事は@hanahiro_aze大先生の[[Symfony4] Symfony Best Practice 定点観測](https://qiita.com/hanahiro_aze/items/1a8c32f5949b0a9fc187)でした。

Symfony4,Symfony3.4がリリースされて大きくSymfonyが変わりつつあります。
まずはサンプルアプリを作ってみようと思い簡単なTodoアプリを作りました。

https://github.com/polidog/sf4-todo


作っている途中で気づいた点を書いていこうと思います。

## Symfonyプロジェクトの作成
以前は`symfony`コマンドを使って新規Symfonyプロジェクトを作成していましたが、`composer create-project`を使うようになりました。

```
$ composer create-project "symfony/skeleton" sf4-todo "4.0.*"
```

`composer.json`を見てみるとsymfonyコマンドを使ってた頃に比べて非常にシンプルになっています。

- symfony/console
- symfony/flex
- symfony/framework-bundle
- symfony/lts
- symfony/yaml

## symfony/ltsとは？

https://github.com/symfony/lts

ちょっと気になったのはsymfony/lts。  

各Symfonyコンポーネントのバージョンを合わせるために作られたようです。
今まではsymfony/symfonyがあったため、各コンポーネントのバージョンが縛られていたのですが、symfony4ではそのようことはないのであえてバージョン縛るために`symfony/lts`を入れてるようです。

## ビルトインサーバの起動

デフォルトではWebServerBundleが入っていないので以下のコマンドを実行してサーバを起動します。

```
php -S 127.0.0.1:8000 -t public
```

あとはブラウザで[locahost:8000](http://localhost:8000)へアクセスします。

僕の場合は`composerコマンド`定義しました。

```json
"scripts": {
    "auto-scripts": {
        "cache:clear": "symfony-cmd",
        "assets:install --symlink --relative %PUBLIC_DIR%": "symfony-cmd"
    },
    "post-install-cmd": [
        "@auto-scripts"
    ],
    "post-update-cmd": [
        "@auto-scripts"
    ],
    "serve": "php -S 127.0.0.1:8000 -t public"
},
```

もちろんWebServerBundleを利用することもできます。

```shell-session
$ composer req symfony/web-server-bundle
```


## Twig,Doctrine,Formを利用する一般的なアプリケーションを作るには

DoctrineORMやFormやTwigなどを開発するには別途用意する必要があります。
私の場合は「Twig」「Doctrine」「symfony/form」「FrameworkExtraBundle」が使えれば一通の開発ができるので、composerで追加しました

```shell-session
$ composer require twig orm annotation form
```

あ、それから開発時にはSymfonyの強力なWebProfilerを使いたいのでそちらも用意しました。

```shell-session
$ composer require --dev profiler
```

## データベースの設定について

`parameters.yml`がなくなって`.env`になる事は把握していましたが、dsnで設定できるようになってしました。

```
# .env
DATABASE_URL=mysql://root:@127.0.0.1:3306/sf4_todo
```

## bin/console doctrine:generate:entitiesが非推奨だった・・・。

なんか気づいたら非推奨になってドキュメントから削除されてた・・・。
https://github.com/symfony/symfony-docs/issues/5070

必要な場合はphpstormでgetter/setterを生成したほうが良さそうですね。


## ServiceEntityRepository
Symfony3.3からAutowiringが最強になったので、カオスなservices.ymlを生成する必要もJMSDiExtraBundleも使う必要がなくなりました。  
https://symfony.com/doc/current/service_container/3.3-di-changes.html

しかしDoctrineのEntityRepositoryを継承してしまったRepositoryはAutowiringの恩恵を受けることができませんでした。

`ServiceEntityRepository`を継承すればそういった問題も解消されます。

```
<?php


namespace App\Repository;


use App\Entity\Todo;
use Doctrine\Bundle\DoctrineBundle\Repository\ServiceEntityRepository;
use Doctrine\Common\Persistence\ManagerRegistry;

class TodoRepository extends ServiceEntityRepository
{
    public function __construct(ManagerRegistry $registry)
    {
        parent::__construct($registry, Todo::class);
    }
}

```

これでAutowiringの恩恵を受けることができます。


ちなみにこれはSymfony3.3から使えるぽいです。。。
全然気づかなかった・・・

https://github.com/doctrine/DoctrineBundle/commit/4efcb135344e55403a0fd193c23a8c7249cfd7d0

## Controllerを継承しないからシンプルになる

[Todo/NewController](https://git.io/vbtAz)とか見てもらえば、わかりますがコントローラがシンプルになります。
継承しないことにより、よりシンプルにかけるような気分になります。

必要なものはすべて勝手にInjectしてくれるし、もはやControllerクラスを継承したり、`$this->get()`みたいなコードを書いたら負けですね。

## Bundle-less Applications
最初Bundle-less Applicationって話を聞いたときは、Bundle使わなくなるとかありえないと思ったんだけど、実際Symfony4触っていて思ったのは、そんなにアプリケーションを作る上でBundleは必要じゃないなぁーと。
もちろん、ディレクトリ的に分けたいことはあるんだけどそれは、対応できるし、ものすごいデカいwebアプリならBundle使いたくなるんだろうけど、私が作っている程度のものであればBundleはいらないなーと。



## 最後に
Symfonyはプロジェクトの作成方法や、ディレクトリ構造,Namespaceとかフレームワークとして変更があった部分は多いのですが、簡単なアプリケーションを作るのであれば、Symfony3系の知識があればそこまで苦労なくキャッチアップできるかと思います。

[symfony/demo](https://github.com/symfony/demo)のコードを読んでみると学べることも多いのでおすすめです。

また、Todoアプリは今後もう少しアップデートしていく予定なので、何か疑問・不満などありましたらissue立てて貰えればと思います。  

ということで、素敵なSymfony4を皆さん使って行きましょう！！！！