Laravel勉強 その3 Laravelに関する設定

## 前回記事
[Laravel勉強 その2 設定の確認](https://qiita.com/masa_skd30/items/a8cf8fbae1bf2097cc0b)

## 目的
- 勉強のため、Laravel 7.xの公式ドキュメントを読み解いていく。
- 今回は、公式ドキュメントの「設定」の章を扱う。

## 参考
[Laravel 7.x 設定](https://readouble.com/laravel/7.x/ja/configuration.html)


## イントロダクション
>Laravelフレームワークの全設定ファイルは、configディレクトリに保存されています。
>各オプションには詳しいコメントが付いているので、各ファイルを一読し、使用できるオプションを把握しておきましょう。

はい。


## 環境設定
>アプリケーションを実行している環境にもとづき、別の設定値に切り替えられると便利です。
>たとえば、ローカルと実働サーバでは、異なったキャッシュドライバを使いたいことでしょう。

>これを簡単にできるようにするため、LaravelではVance Lucas氏により作成された、DotEnv PHPライブラリーを使用しています。
>新たにLaravelをインストールすると、アプリケーションのルートディレクトリには、.env.exampleファイルが含まれています。
>ComposerによりLaravelをインストールした場合は自動的に、このファイルは.envに名前が変更されます。
>Composerを使わずにインストールした場合は、名前を変更してください。

```  
# ls -alt /var/project/server/.env*
-rw-rw-r-- 1 root root 829  5月 22 16:46 /var/project/server/.env
-rw-rw-r-- 1 root root 778  5月 21 20:33 /var/project/server/.env.example

# diff /var/project/server/.env{,.example}
3c3
< APP_KEY=****************************　←実際にはKEYが記載されている
---
> APP_KEY=
```  

確かにあった。
差分は、前回APP_KEYを設定したもの。

>.envファイルは、アプリケーションのソースコントロールに含めるべきでありません。
>各ユーザー／サーバは異なった環境設定が必要だからです。
>さらに、侵入者がソースコントロールリポジトリへアクセスすることが起きれば、機密性の高い情報が漏れてしまうセキュリティリスクになります。

.envは簡単に触れるようにしないほうがってことね。
確かにAPP_KEYとかもあるからわかる気がする。

>チーム開発を行っている場合、.env.exampleファイルをアプリケーションに含めたいと思うでしょう。
>サンプルの設定ファイルに、プレースホルダーとして値を設定しておけば、チームの他の開発者は、アプリケーションを実行するために必要な環境変数をはっきりと理解できるでしょう。

要は、.envにどんな環境変数を持たせればいいかがわかるためのサンプルとして使ってね、ってことかと。

>さらに、.env.testingファイルを作成することもできます。
>このファイルは、PHPUnitテスト実行時やArtisanコマンドへ--env=testingオプションを指定した場合に、.envファイルをオーバーライドします。

.env.testingというファイルを作っておけば、オプションを使って.env.testingに記載された環境変数を使用できる、ということね。

>Tip!! .envファイルにあるすべての変数は、サーバレベルやシステムレベルで定義されている、外部の環境変数によってオーバーライドすることができます。

優先度が決まっているということかと。
サーバー・システムレベルの環境変数　＞　.envファイル内の環境変数


### 環境変数タイプ

>.envファイル中の全変数は、文字列としてパースされます。env()関数でさまざまなタイプを返すために、予約語があります。

| .env値         | env()値      |
| -------------- | ------------ |
| true, (true)   | (bool) true  |
| false, (false) | (bool) false |
| empty, (empty) | (string)""   |
| null, (null)   | (null)null       | 

要はtrueとかfalseとかは文字列として認識されないようにしている、ということだと思う。

### 環境設定の取得

>このファイルにリストしている値は、アプリケーションがリクエストを受け取った時点で、$_ENV PHPスーパーグローバル変数へロードされます。
>しかし、設定ファイルの変数をenvヘルパを使用して、値を取得できます。
>実際にLaravelの設定ファイルを見てもらえば、このヘルパで多くのオプションが使われているのに気がつくでしょう。

```
'debug' => env('APP_DEBUG', false),
```

>env関数の第２引数は「デフォルト値」です。この値は指定したキーの環境変数が存在しない場合に返されます。

envヘルパって何？と思って調べてみたら、要はグローバルな関数ということみたい。（ちょっと違う？）
env関数の場合は、第1引数に指定した値をとってきて、なかったら第2引数の値になるとのこと。
ちなみに第2引数は省略しても良いらしい。

### 現在環境の決定

>現在のアプリケーション環境は、.envファイルのAPP_ENV変数により決まります。
>APPファサードのenvironmentメソッドにより、この値へアクセスできます。

```
$environment = App::environment();
```

>指定した値と一致する環境であるかを確認するために、environmentメソッドへ引数を渡すこともできます。
>必要であれば、複数の値をenvironmentメソッドへ渡せます。値のどれかと一致すれば、メソッドはtrueを返します。

```
if (App::environment('local')) {
    // 環境はlocal
}

if (App::environment(['local', 'staging'])) {
    // 環境はlocalかstaging
}
```

>Tip!! 現在のアプリケーション環境は、サーバレベルのAPP_ENV環境変数によりオーバーライドされます。
>これは同じアプリケーションを異なった環境で実行する場合に便利です。特定のホストに対し、サーバの設定で適切な環境を指定できます。

App:environmentを使用して環境名を取得したり、引数に記載した環境名と合っているか確認ができる、ということみたい。
ただ、具体的な使い道がわからん。。。

### デバッグページの環境変数非表示

>例外が補足されず、APP_DEBUG環境変数がtrueになっていると、すべての環境変数とその内容がデバッグページに表示されます。
>特定の変数は非表示にしたい場合があるでしょう。
>config/app.php設定ファイルのdebug_blacklistオプションを更新してください。

>いくつかの変数は、環境変数とサーバ／リクエストデータの両方で利用できます。そのため、$_ENVと$_SERVER両方のブラックリストへ登録する必要があります。

```
return [

    // ...

    'debug_blacklist' => [
        '_ENV' => [
            'APP_KEY',
            'DB_PASSWORD',
        ],

        '_SERVER' => [
            'APP_KEY',
            'DB_PASSWORD',
        ],

        '_POST' => [
            'password',
        ],
    ],
];
```

デバッグをONにすると、デバッグページに環境変数が記載される。
暗号化キーやDBのPWなど、表示したらマズイものは、debug_blacklistで指定しておきましょう、ということ。

### 設定値へのアクセス

>アプリケーションのどこからでもグローバルのconfigヘルパ関数を使用し、設定値へ簡単にアクセスできます。
>設定値はファイルとオプションの名前を含む「ドット」記法を使いアクセスします。
>デフォルト値も指定でき、設定オプションが存在しない場合に、返されます。

```
$value = config('app.timezone');

// 設定値が存在しない場合、デフォルト値を取得する
$value = config('app.timezone', Asia/Seoul');
```

>実行時に設定値をセットするには、configヘルパへ配列で渡してください。

``` 
config(['app.timezone' => 'America/Chicago']);
``` 

config関数で、設定ファイルから値をとったり、値を入れたりすることができるとのこと。


### 設定キャッシュ

>アプリケーションをスピードアップさせるために、全設定ファイルを一つのファイルへまとめる、config:cache Artisanコマンドを使ってください。
>これによりアプリケーションの全設定ファイルのオプションが、単一のファイルに結合され、フレームワークが素早くロードできるようになります。

>一般的には、本番環境へのデプロイ作業の一環として、php artisan config:cacheコマンドを実行すべきでしょう。
>アプリケーションの開発期間中は設定が頻繁に変更されることも多いので、ローカルでの開発中にこのコマンドを実行してはいけません。

>Note: 開発過程の一環としてconfig:cacheコマンド実行を採用する場合は、必ずenv関数を設定ファイルの中だけで使用してください。
>設定ファイルがキャッシュされると、.envファイルはロードされなくなり、env関数の呼び出しはすべてnullを返します。

php artisan config:cache
を実行すれば、設定ファイルの内容をまとめて、キャッシュに書き込むことができるとのこと。
ただし、これを実行してしまうと、設定を変更しても反映されないし、env関数も使えなくなってしまうとのこと。

### メンテナンスモード

>アプリケーションをメンテナンスモードにすると、アプリケーションに対するリクエストに対し、すべてカスタムビューが表示されるようになります。
>アプリケーションのアップデート中や、メンテナンス中に、アプリケーションを簡単に「停止」状態にできます。
>メンテナンスモードのチェックは、アプリケーションのデフォルトミドルウェアスタックに含まれています。
>アプリケーションがメンテナンスモードの時、ステータスコード503でMaintenanceModeException例外が投げられます。

>メンテナンスモードにするには、down Artisanコマンドを実行します。
```
php artisan down
```

要は、メンテナンス時間とかでアプリケーションを実行したくないときにこのコマンドを使用すると、メンテナンスモードでアプリケーションを実行できるとのこと。
メンテナンス中は、カスタムビュー（指定したメンテナンス画面）を返してくれるし、ステータスコードも503になるとのこと。
メンテナンス画面を出す仕組みを結構作りこんでいたシステムを扱っていたこともあるけど、Laravelなら簡単にできちゃうのね。

>downコマンドには、messageとretryオプションを付けることもできます。
>messageの値はカスタムメッセージを表示、もしくはログするために使用し、retryの値はHTTPヘッダのRetry-Afterとしてセットされます。

```
php artisan down --message="Upgrading Database" --retry=60
```

オプション次第で、画面に表示されるメッセージを変更したり、
Retry-Afterヘッダー（いつメンテナンスが終わるよーとか、メンテナンスまで何秒だよーとかを伝える）を指定したりできると。

>コマンドのallowオプションを使用し、メンテナンスモードであっても、アプリケーションへアクセスを許すIPアドレスやネットワークを指定できます。

```
php artisan down --allow=127.0.0.1 --allow=192.168.0.0/16
```

特定のIP・ネットワークからのアクセスを許可することで、メンテナンスを継続したままアプリケーションを実行できると。
使い道としては、リリース作業後の確認作業とかに使うのかと思われ。
これも作りこんでいたなあ。。。

>メンテナンスモードから抜けるには、upコマンドを使います。

```
php artisan up
```

で、これがメンテナンスモードの終了。

>Tip!! resources/views/errors/503.blade.phpを独自に定義することにより、メンテナンスモードのデフォルトテンプレートをカスタマイズできます。

ここに置いたものがカスタムビューってことかと。

#### メンテナンスモードとキュー
>アプリケーションがメンテナンスモードの間、キューされたジョブは実行されません。
>メンテナンスモードから抜け、アプリケーションが通常状態へ戻った時点で、ジョブは続けて処理されます。

#### メンテナンスモードの代替
>メンテナンスモードでは、アプリケーションがその間ダウンタイムになってしまいますので、Laravelでの開発でゼロダウンタイムを実現するEnvoyerのような代替サービスを検討してください。

[Envoyer](https://envoyer.io/)は、ダウンタイムなしでデプロイをしてくれるサービスらしい。
こういうのもあるのね。





3回目は以上。