[Laravel] ドキュメントの概念について調べて見た

# Laravelのドキュメントにおける概念について調べて見た

## 前置き
調べたかったから調べました。
この調べはLaravelの日本語ドキュメントにおける流れに沿って制作しています。
今回まとめた結果を図にまとめるとこんな感じ
![さ.png](https://qiita-image-store.s3.amazonaws.com/0/240192/a506722f-fc48-e522-84c2-585447ce5047.png)



## 概論 : はじまり

### 初めの読み込み index.php
>全てのリクエストはまずはじめにindex.phpにたどり着く。Laravelにおいて、このindex.phpはフレームワークを読み取る入り口でしかありません。
　index.phpではLaravel等のcomposerでダウンロードしたライブラリなどで生成されたクラス等の定義をしたファイルを読み取ります。

　とありますが、どんな感じで動いているのか気になったので何を読み込んでいるのか見ていきましょう。
まずはじめにindex.phpの中身を見て見ましょう。

``` public/index.php
<?php

/**
 * Laravel - A PHP Framework For Web Artisans
 *
 * @package  Laravel
 * @author   Taylor Otwell <taylor@laravel.com>
 */

define('LARAVEL_START', microtime(true));

/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader for
| our application. We just need to utilize it! We'll simply require it
| into the script here so that we don't have to worry about manual
| loading any of our classes later on. It feels great to relax.
|
*/

require __DIR__.'/../vendor/autoload.php';

/*
|--------------------------------------------------------------------------
| Turn On The Lights
|--------------------------------------------------------------------------
|
| We need to illuminate PHP development, so let us turn on the lights.
| This bootstraps the framework and gets it ready for use, then it
| will load up this application so that we can run it and send
| the responses back to the browser and delight our users.
|
*/

$app = require_once __DIR__.'/../bootstrap/app.php';

/*
|--------------------------------------------------------------------------
| Run The Application
|--------------------------------------------------------------------------
|
| Once we have the application, we can handle the incoming request
| through the kernel, and send the associated response back to
| the client's browser allowing them to enjoy the creative
| and wonderful application we have prepared for them.
|
*/

$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);

$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

$response->send();

$kernel->terminate($request, $response);

```

index.phpはこのように記載されておりまずはじめに`require __DIR__.'/../vendor/autoload.php';`を読み込んでいます。
この際の読み込みは下記のようになります。

- ClassLoader.php<br/>
    [PSR-0](http://www.infiniteloop.co.jp/docs/psr/psr-0.html)と [PSR-4](https://qiita.com/inouet/items/0208237629496070bbd4)に準拠して各種クラスを読み込む関数を定義
- autoload_static.php <br/>
    Laravelの基礎になったsymphonyやLaravel自体のクラス読み込みを行なっている。つまりユーザーによって変化を起こさないClassの読み込みを行なっていると思われる
- autoload_namespaces.php
    下記のものを取得するために利用される。
    
 - [Prophecy](https://qiita.com/Hiraku/items/326b58c586a134d2ea74)
 - [Parsedown](https://qiita.com/naga3/items/eb638d90e77fa0e1ae0b)
 - [Mockery](https://qiita.com/ichi944/items/bc596a544d90dbe944cc)
 - [PHP Console Highlighter](https://github.com/linuxserver/Heimdall/tree/master/vendor/jakub-onderka/php-console-highlighter/src/JakubOnderka/PhpConsoleHighlighter) - [Php Console Color](https://github.com/linuxserver/Heimdall/tree/master/vendor/jakub-onderka/php-console-color)
 - [doctrine](http://techblog.kayac.com/symfony-doctrine.html)


    を呼び出しています。主にこれらはユニットテストやコンソール装飾、またドクトリンの拡張のために読み込まれていると想定されます。

- autoload_psr4.php<br/>
    読み込んだnamespaceにおける全てのClassをオートロードしていると思われる。
- autoload_classmap.php <br/>
    名前のままcomposerで読み込んだフレームワークやライブラリを全てわかりやすくMap化しています。多分ココを見れば元のファイルを眺めることができる。
- autoload_files.php<br/>
    最後の総仕上げで読み込んだsymphonyなどのフレームワークやライブラリなど最初に読み込むべきファイルを読み込むためのものだと思われる。

### 次に読み込むのは bootstrap/app.php
>その後bootstrap/app.phpファイルを読み取り、Laravelアプリケーションのインスタンスを取得します。
この時Laravelが初めてアクションを起こし、アプリケーション／サービスコンテナのインスタンスを生成します。

とありますが、どんな動きをしているのでしょうか？`$app = require_once __DIR__.'/../bootstrap/app.php';`

まずはじめにココでは書かれている通りにAPP/サービスコンテナのインスタンスを生成しています。その後[Singleton](https://qiita.com/Shuuuuuuun/items/0d6f809e8c55fe898ebd)を利用し、HttpやconsoleといったkernelやHandlerをまとめ、このサービスコンテナにおけるリクエストの一元化を行います。
この際Laravelの元となっているSymfonyの基幹部とその拡張を行うLaravelのkernelが処理を行なっているようです。
内部では`$middleware`,`$middlewareGroups`,`$routeMiddleware`の定義を行なっています。
今回はHTTPカーネルを代表で見ていきましょう。
**\$middleware**

```
protected $middleware = [
    \Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode::class,
    \Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
    \App\Http\Middleware\TrimStrings::class,
    \Illuminate\Foundation\Http\Middleware\ConvertEmptyStringsToNull::class,
    \App\Http\Middleware\TrustProxies::class,
];
```
- [メンテナンスモード](https://laravel.com/docs/5.3/configuration#maintenance-mode)の確認
- [POSTサイズの確認](https://github.com/jimrubenstein/laravel-framework/blob/master/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php)
- [文字のトリム](https://www.larajapan.com/2015/10/19/%E5%85%A5%E5%8A%9B%E3%81%AE%E7%A9%BA%E7%99%BD%E6%96%87%E5%AD%97%E3%82%92%E3%83%88%E3%83%AA%E3%83%A0%EF%BC%88%EF%BC%91%EF%BC%89-%E3%83%9F%E3%83%89%E3%83%AB%E3%82%A6%E3%82%A7%E3%82%A2/)
- [空文字をnullへ置き換え](https://mseeeen.msen.jp/laravel-5-4-trouble-with-convertemptystringstonull-middleware/)
- [トラステッドプロキシ統合](https://qiita.com/piotzkhider/items/934dd9aed9adfabc699b#trusted-proxy-integration)
このmiddlewareはHTTPのリクエストの実行前に処理を行うものを定義したものとされています。
つまるところ、`$middleware`ではエラーを防ぐための処理だとおもわれます。

**\$middlewareGroups,\$routeMiddleware**

これに関してはすごく詳しく書いてあったものがあったので[こちら](https://qiita.com/kurikazu/items/0c57f050f5dfef02b23e#routemiddleware)を参照
一応軽く触れておきます。
***Web***

- EncryptCookies :
　Cookieの暗号・復号処理
- AddQueuedCookiesToResponse :
　Cookieをレスポンスヘッダに登録
- StartSession :
　Sessionを生成取得処理
- ShareErrorsFromSession :
　Sessionに保存したエラーをViewにセットする
- VerifyCsrfToken :
　CSRFトークンやチェックを行う機能
- SubstituteBindings :
　Route Model Binding を実行する機能

***API***

- throttle:60,1
→$routeMiddleware の throttleを参照
- bindings
→ $routeMiddleware の bindingsを参照

**routeMiddleware**

```
protected $routeMiddleware = [
    'auth' => \Illuminate\Auth\Middleware\Authenticate::class,
    'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
    'bindings' => \Illuminate\Routing\Middleware\SubstituteBindings::class,
    'cache.headers' => \Illuminate\Http\Middleware\SetCacheHeaders::class,
    'can' => \Illuminate\Auth\Middleware\Authorize::class,
    'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
    'signed' => \Illuminate\Routing\Middleware\ValidateSignature::class,
    'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
];
```
- auth
 そのルートでのユーザー認証を必須とする
- auth.basic
 そのルートでのBasic認証を必須とする
- bindings
 Route Model Binding を実行する
- cache.headers
 ヘッダーのキャッシュをセットする
- can
 アクションに対してポリシーを付与する
- guest
 認証済かチェックし、認証済であれば /home にリダイレクトする機能
- signed
 署名付きルートのための署名処理
- throttle
 同一ユーザーが単位時間内に規定回数以上のアクセスを行ったかどうかチェックする機能

 主にこの`bootstrap/app.php`ではセキュリティに関するものが多くリクエストの処理を柔軟に行えるのが特徴と思われる。さらにこのカーネルにはhandleメソッドが使われておりすごくシンプルで、Requestを受け取り、Responseをリターンすることから、カーネルをアプリケーション全体を表す大きなブラックボックスだと考えるのが妥当かと思われる。

### サービスプロバイダ
>サービスプロバイダはデータベース、キュー、バリデーション、ルーティングなど、フレームワークの様々なコンポーネントの初期起動処理に責任をもちます。フレームワークにより提供されている全機能を初期化し、設定するものですから、サービスプロバイダはLaravelの初期処理の過程全体で一番重要な機能です。

　カーネル起動時に読み込まれるconfigは`\Illuminate\Foundation\Bootstrap\RegisterProviders::class`のBootstrap methodで呼び出されます。

```
public function registerConfiguredProviders()
{
    $providers = Collection::make($this->config['app.providers'])
                    ->partition(function ($provider) {
                        return Str::startsWith($provider, 'Illuminate\\');
                    });

    $providers->splice(1, 0, [$this->make(PackageManifest::class)->providers()]);

    (new ProviderRepository($this, new Filesystem, $this->getCachedServicesPath()))
                ->load($providers->collapse()->toArray());
}
```

```
public function getCachedServicesPath()
{
    return $this->bootstrapPath().'/cache/services.php';
}
```

```
public function bootstrapPath($path = '')
{
    return $this->basePath.DIRECTORY_SEPARATOR.'bootstrap'.($path ? DIRECTORY_SEPARATOR.$path : $path);
}
```
ProviderRepositoryに登録を行い、それをロードしていることがわかります。
この際にキャッシュされたservice.phpをもとにLoadを行うためにLoad内では$providers内部の配列を一度解体し、際配列化しています。

その後、bootを行います。
この際、`\Illuminate\Foundation\Bootstrap\BootProviders::class`ではbootメソッドを呼び出します。
これは、最初の起動の際に読み込まれますが起動済みであればこの動作は行わないで済みます。

### リクエストのディスパッチ
> アプリケーションの初期処理が済み、全サービスプロバイダが登録されたら、ディスパッチ（実行制御の移行）するためにルーターへRequestが手渡されます。ルーターはそのリクエストをルートかコントローラにディスパッチし、その時にルートに指定されているミドルウェアも実行されます。

```
protected function dispatchToRouter()
{
    return function ($request) {
        $this->app->instance('request', $request);

        return $this->router->dispatch($request);
    };
}
```

参考
[PSR-0について](http://www.infiniteloop.co.jp/docs/psr/psr-0.html)
[PSR-4について](https://qiita.com/inouet/items/0208237629496070bbd4)
[Prophecy](https://qiita.com/Hiraku/items/326b58c586a134d2ea74)
[Parsedown](https://qiita.com/naga3/items/eb638d90e77fa0e1ae0b)
[Mockery](https://qiita.com/ichi944/items/bc596a544d90dbe944cc)
[PHP Console Highlighter](https://github.com/linuxserver/Heimdall/tree/master/vendor/jakub-onderka/php-console-highlighter/src/JakubOnderka/PhpConsoleHighlighter)
[Php Console Color](https://github.com/linuxserver/Heimdall/tree/master/vendor/jakub-onderka/php-console-color)
[doctrine](http://techblog.kayac.com/symfony-doctrine.html)
[Singleton](https://qiita.com/Shuuuuuuun/items/0d6f809e8c55fe898ebd)
[メンテナンスモードについて](https://laravel.com/docs/5.3/configuration#maintenance-mode)
[POSTサイズの確認](https://github.com/jimrubenstein/laravel-framework/blob/master/src/Illuminate/Foundation/Http/Middleware/ValidatePostSize.php)
[文字のトリム](https://www.larajapan.com/2015/10/19/%E5%85%A5%E5%8A%9B%E3%81%AE%E7%A9%BA%E7%99%BD%E6%96%87%E5%AD%97%E3%82%92%E3%83%88%E3%83%AA%E3%83%A0%EF%BC%88%EF%BC%91%EF%BC%89-%E3%83%9F%E3%83%89%E3%83%AB%E3%82%A6%E3%82%A7%E3%82%A2/)
[空文字をnullへ置き換え](https://mseeeen.msen.jp/laravel-5-4-trouble-with-convertemptystringstonull-middleware/)
[トラステッドプロキシ統合](https://qiita.com/piotzkhider/items/934dd9aed9adfabc699b#trusted-proxy-integration)
[middlewaregroupまとめ](https://qiita.com/kurikazu/items/0c57f050f5dfef02b23e#routemiddleware)
[laravel.com/api](https://laravel.com/api/5.6/Illuminate.html)
[laravel.com/docs/5.3/middleware](https://laravel.com/docs/5.3/middleware#middleware-groups)
[日本語ドキュメント](https://readouble.com/laravel/5.5/ja/lifecycle.html)