Symfony-Standard3.4の環境変数（env）の設定元について

## はじめに

以下の記事はSymfonyではなくSymfony-Standardなので注意。
というかこれ調べるまでSymfonyって１つしかないと思ってて、SymfonyとSymfony-Standardで分かれていると思ってなかった。

https://github.com/symfony/symfony/tree/3.4

https://github.com/symfony/symfony-standard/tree/3.4

何がどう違うのかの説明は割愛。
というか知らん。

## きっかけ

企業案件なので詳細は記載できないが、きっかけは `$this->getEnvironment()`を基に条件判定している箇所があり、本番環境への影響調査をしている過程において。

## $this->getEnvironment()

### アプリ内部

ドキュメントルートにて、本番環境では`app.php`を、本番環境以外では`app_dev.php`を指定するように示唆するようなことが公式に記載されている。

https://symfony.com/doc/3.4/quick_tour/the_big_picture.html#what-is-an-environment

> 環境とは
> 環境は、アプリケーションの実行に使用される構成のグループを表します。symfony はデフォルトで 2 つの環境を定義します: dev(アプ> リケーションをローカルで開発する場合に適しています) とprod(本番環境でアプリケーションを実行する場合に最適化されています)。
> 
> http://localhost:8000ブラウザーで URLにアクセスすると、dev環境で Symfony アプリケーションが実行されます。環境内のア> プリケーションにアクセスするにはprod、http://localhost:8000/app.php 代わりに URL にアクセスしてください。devURL に> 常に環境を表示したい場合は、 http://localhost:8000/app_dev.phpURL にアクセスしてください。

`app.php`や`app_dev.php`がURLに入っていたのでは見てくれが悪いので、、、とまで言えばわかるだろうか。
apacheやnginxなどでドキュメントルートの設定やシンボリックシンクなどでアクセスを飛ばす設定をしたことがある方はここまで記載すればピンときていることだろう。

前置き（前提情報）はここまでとし、AppKernelクラスで継承しているKernelクラスを見るとコンストラクトで第一引数として環境変数を受け取り内部プロパティーにセットし、ゲッターも用意されている。

* https://github.com/symfony/http-kernel/blob/3.4/Kernel.php#L84-L90
* https://github.com/symfony/http-kernel/blob/3.4/Kernel.php#L322-L325

このゲッターこそが、きっかけで記載している`$this->getEnvironment()`だ。

少し話を遡り、`app.php`と`app_dev.php`ではAppKernelをインスタンス化する際に直書きで環境名を指定し、第一引数に渡している。

https://github.com/symfony/symfony-standard/search?q=AppKernel

つまり、`$this->getEnvironment()`で取得できる値の設定基は、`app.php`と`app_dev.php`ということが判明した。

個人的には、サーバー内で変数定義等によって設定されているものと思っていたので
config配下や.envやphp.iniやconf.dあたりをずっと探していたが、まさかハードコーティングされている作りになっているとは思っていなかったのでここに辿り着くまでにかなりの時間を要した。

### コンソールコマンド

bin/consoleコマンドにてenvオプション指定時の値が取得される

```bash
php bin/console --env=test {your-command}
```

```php
dump($this->getEnvironment()); // test が表示される
```

---

bin/consoleコマンドにてenvオプション未指定時にはデフォルト値である`dev`が取得される

https://symfony.com/doc/current/console.html#app-env-app-debug

```bash
php bin/console {your-command}
```

```php
dump($this->getEnvironment()); // dev が表示される
```

---

一応、内部的な処理を補足しておくと、直前のリンクを見ていて勘の良い方は気づいただろうが、
コマンド実行時は`app.php`と`app_dev.php`は経由していなくて、
代わりに`bin/console`を経由して初期化を行なっている。

https://github.com/symfony/symfony-standard/search?q=AppKernel

以下の部分だが、コマンド実行時のenvオプション指定時の値がAppKernelの第一引数に渡されている仕組みになっている。

```php
$env = $input->getParameterOption(array('--env', '-e'), getenv('SYMFONY_ENV') ?: 'dev');
$kernel = new AppKernel($env, $debug);
$application = new Application($kernel);
$application->run($input);
```

筆者はLaravel派なのでSymfonyは詳しくはないが、多分ここがLaravelと異なるところだと思う。
とか書いておきながらLaravelはどうなっていたか記憶が曖昧だ。
思い出したらSymfonyとLaravelのこのあたりの構造の違いを記載しようと思う。
似たような感じになってたらごめん。

## $this->getParameter(‘server_env’)

### アプリ内部

.envに記載の内容が取得される

### コンソールコマンド

.envに記載の内容が取得される

## まとめ

* $this->getEnvironment()は、`app.php`と`app_dev.php`で直書きされている値が基となっている。
* $this->getParameter(‘server_env’)は、.envで値が設定されている。


`app.php`は本番用なので最高のパフォーマンスが得られるように最適化されているようだけど、
個人的には、`app.php`と`app_dev.php`の処理内容は`AppKernel.php`の方で`$this->getParameter(‘server_env’)`で判定して処理切り分けたら環境変数の一元化ができてややこしくないのに、、、と思うけど恐らく、フレームワークのライフサイクルの関係でコンテナサービスが初期化される前の処理部分だろうからこういう作りになってるんだろうなぁと推測します。


## 宣伝

会社も人間も一緒に成長していける仲間を探しています。

https://gild.co.jp/recruit-career/backend-engineer-20180722

組織拡大のため、２社目設立創業メンバーも募集しています。
2023/3創業予定。

* 採用活動（Wantedlyへの求人記事執筆等...）
* 自社プロダクト開発
* 経理業務
* 労務業務
* クライアント先からの仕事依頼
* ２社目のコーポレートサイト制作

最近子どもを授かりました。
やることいっぱいあって一人じゃ手が回っていません。助けてください。
筆者がたまにおかしいときがあります。
１社目は創業５年目に突入していますが名もなき小さな会社なので採用が難しいです。
優秀な人材はまず獲得できないと思っていて、一緒に試行錯誤していってくれる仲間が欲しいです。
会社作りへの情熱や意識は太陽に照り付けられている海のようにギラギラしています。