Symfony Handson lesson-1

# この記事について
Udemyの動画講義，"Symfony 6 Framework Hands-On 2023"についての備忘録です
https://www.udemy.com/course/symfony-framework-hands-on/
Symfony6について，TwitterクローンのWebアプリを開発しながら学習するという内容になっています

# Symfony 101
## 基本コマンド
```
# Symfonyの要件チェック
symfony check:require

# プロジェクトの作成
symfony new symfony-handson --version="6.1.*"

# プロジェクトの起動
symfony server:start

# コマンド一覧
symfony console

# プロジェクトでの脆弱性の確認
symfony check:security
```

## プロジェクト構成
bin/
- Symfonyコンソール
- 基本的に編集する必要なし

config/
- プロジェクトの構成ファイル

public/
- エントリポイント
- スタイルシート，Javascript，画像，その他アセット等も配置される

src/
- Controller等
- アプリケーションのすべてのビジネスロジック

var/
- キャッシュ，ログ等

vendor/
- サードパーティライブラリ
- 直接変更することはない

composer.json
- すべての外部ライブラリ等を定義

composer.lock
- 直接変更はしない
- インストールされた依存関係等をリスト表示

.env
- 環境変数を定義

## 処理の流れ
ブラウザからのリクエスト
→HTTP Server→PHP Binary→Symfony Application(index.php)→Controller→テンプレート等のレスポンス→HTTP Server
→ブラウザへレスポンスを返す

## Controllerの作成
src/Controller/HelloController.phpを作成
```
<?php

namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;

class HelloController {
  public function index() {
    return new Response("Hi!");
  }
}
```

ルーティングを定義
config/routes.phpに以下を追記
```
app_index:
    path: /
    controller: App\Controller\HelloController::index
```

これによって，symfony server:startコマンドで取得したURL（https://127.0.0.1:8000）でHelloControllerが読み込まれ，画面上にHi!と表示される

メモ
- コントローラーを定義したらルート定義を併せて行う
- Controllerの1つのファイルで複数クラスを定義してはならない
- symfony console debug:routerコマンドですべてのルートとコントローラーを表示できる

## ルートの簡易定義
Controllerに以下のように追記することでルート定義をController内で行える
```
  #[Route('/', name: 'app_index')]
  public function index(): Response {
    return new Response("Hi!");
  }
```

## Twig
Twigとは
- Symfonyのテンプレートエンジン（HTMLとデータを併せて表示）
- composer require twigでインストール
- 基本的にはtemplate/に配置
    - HelloControllerに使用するTwigであればtemplate/hello/xxx.html.twig

以下のように，テンプレートエンジンをレスポンスとして返すことでHTMLにデータを埋め込める
- $this->render('Twigへのパス', データ);
```HelloController.php
  #[Route('/{limit<\d+>?3}', name: 'app_index')]
  public function index(int $limit): Response {
    return $this->render('hello/index.html.twig', 
      ['message' => implode(',', array_slice($this->messages, 0, $limit))]
    );
  }
```

Controllerから受け取った変数は{{  }}で表示
```hello/index.html.twig
<div>
  {{ message }}
</div>
```

render等
- https://symfony.com/doc/current/reference/twig_reference.html

テンプレート継承
- 親テンプレートの中で子テンプレートを表示させられる

```親テンプレート
{% block body %}{% endblock %}
```

```子テンプレート
{% extends '親テンプレート名' %}

{% block body %}
// テンプレートを記述
{% endblock %}
```

for構文・if構文
- 通常のプログラミングと同様に使用可能
```使用例
  {% if messages|length > 0 %}
    {% for message in messages %}
      <div>{{ message }}</div>
    {% endfor %}
  {% else %}
    There's nothing yet!  
  {% endif %}
```

フィルタ・関数
- ドキュメント【フィルタ】：https://twig.symfony.com/doc/3.x/filters/index.html
- ドキュメント【関数】：https://twig.symfony.com/doc/3.x/functions/index.html
- 例えば，messages|lengthは配列の要素数を返す


テンプレートの再利用
- {{ incluce("呼び出すTwigのパス", {渡し先のデータ名: 渡すデータ}) }}

```呼び出し元のTwig
{{ include("hello/_message.html.twig", {message: message}) }}
```

```hello/_message.html.twig（呼び出し先のTwig）
<div>This is message.</div>
<div>{{ message }}</div>
```

## リンクの生成
pathを利用
- https://symfony.com/doc/current/reference/twig_reference.html#path
- path('遷移先のルート', {データ名: 渡したいデータ})

```example
<a href="{{ path('app_show_one', { id: key }) }}">{{ message.message }}</a>
```

## コードの自動生成
Maker Bundle
- https://symfony.com/bundles/SymfonyMakerBundle/current/index.html
- 以下コマンドでインストール
    - composer require --dev symfony/maker-bundle
- 以下コマンドで一覧
    - symfony console list make

Controllerの自動作成
- 以下コマンドを実行
    - symfony console make:controller
- 任意のコントローラー名を入力

## profiler
注意
- 本番環境にインストールしたり有効にしてはいけない

profilerとは
- https://symfony.com/doc/current/profiler.html
- 開発環境上でのデバッグツール
    - リクエスト，レスポンス，パフォーマンス，SQL，コントローラー等を確認できる
- 以下コマンドでインストール
    - composer require --dev symfony/profiler-pack

ステータスコード，コントローラー，ルート名等
![スクリーンショット 2023-05-07 21.42.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/45293791-c4da-997e-f1f1-5dc3385926e9.png)

ページ生成にかかった時間
![スクリーンショット 2023-05-07 21.44.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/0c3fca83-737a-6f21-399d-8336d3209243.png)

リクエストを処理するのに必要なメモリ量，レンダリング時間
![スクリーンショット 2023-05-07 21.44.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/de635054-256b-6bb3-b648-c8d9905f2200.png)

リクエストとかレスポンスが見れる
![スクリーンショット 2023-05-07 21.49.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/0e8572bf-1805-a2a2-0feb-f060443d6cd5.png)

それぞれのファイル処理時間や全体のフローも分かる
![スクリーンショット 2023-05-07 21.49.27.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/955c13d2-814b-9e78-d7de-1cc0d5b345ec.png)

ルートの一覧を確認
![スクリーンショット 2023-05-07 21.51.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/25303ab7-aa43-a4f8-3abe-5115ea3375b6.png)

Twigに関する情報
![スクリーンショット 2023-05-07 21.52.23.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/be573ca7-9dfb-fe08-ef9c-38f996d420ba.png)

過去のリクエストも見れる
![スクリーンショット 2023-05-07 21.54.26.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/27dcb5a8-9104-6fe7-5cca-48607988091f.png)

上部のリンクをクリックして戻れる
![スクリーンショット 2023-05-07 21.55.59.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/519081/42dad99c-fc89-9502-2da0-d5e5613b3836.png)

**パフォーマンスの悪いボトルネックを発見するのに便利**

# 最後に
昔Symfonyの公式ドキュメントのチュートリアルを触ったことがあり，今回の内容はほぼチュートリアルの内容でした（ただしチュートリアル以降はほぼ触ってなかった）
最後のProfilerはほぼ見たことなかったのですごく便利そうだと思いました
https://symfony.com/doc/current/setup.html

最近アウトプットしてなかったので，次回以降も備忘録的に書いていこうと思います（かなり雑メモになってしまった）
ではまた