Laravelアプリが動く流れを簡単に書いてみた


流れ図

                   ----------------- 
     request ->    public/index.php
     response <-   -----------------
                         ↓ ↑
                   -------------------
                   app/Http/Kernel.php
                   -------------------
                         ↓ ↑
                   ----------------------
                   ルータ・routes/web.php
                   ----------------------
                         ↓ ↑
                   -----------------
                     ミドルウェア
                   -----------------
                         ↓ ↑
                   -----------------
                     コントローラ-      → view
                   -----------------  ←

おおまかな流れ

index.phpではまずリクエストを受け取り、アプリが動くなどのもろもろの設定を行い、ルータに渡すまでを行う。

routes/web.phpに従って動き、middleware->controller->viewと流れて、今度は逆流れになる

index.phpでresponseを受け取り、responseを出力

詳しく見ていく

public/index.php

エントリポイント(アプリケーションの起点)
HTTPリクエストを受けとるため、Webサーバのドキュメントルート配下に置くとアクセスできる。

index.php
define('LARAVEL_START', microtime(true)); 

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

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

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

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

$response->send();

$kernel->terminate($request, $response);
define('LARAVEL_START', microtime(true)); 

現在の時間を定義(constではなく、defineなのは、microtime関数を使用しているため)
[microtime]https://amatou-papa.com/php-microtime/
[define]https://qiita.com/Hiraku/items/bb0cb665d830f7cd37ff

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

オートロード機能 requireを書きまくる必要ない。これを使うために、composerを使用して、ライブラリをインストールすると、vendor/autoload.phpというファイルができる。このオートロード実体ファイルをrequireすることで、vendor配下のライブラリをすべて自動で、ロードしてくれる。

composer.jsonでautoloadファイルを決めている。
つまり、このファイルにオートロードするファイルを追加して、コマンドをたたけば、使えるようになる
コマンドcomposer dump-autoload composer.jsonを元にファイル群を生成し、オートロードする内容が決まる
[オートロード]https://laraweb.net/surrounding/1642/

autoload.phpの中では、ユニットテストや全classのオートロードやフレームワーク(symphony)やライブラリなどを読み込む

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

詳しくファイルを見てみる。

app.php
$app = new Illuminate\Foundation\Application(
    $_ENV['APP_BASE_PATH'] ?? dirname(__DIR__)
);
$app->singleton(
    Illuminate\Contracts\Http\Kernel::class,
    App\Http\Kernel::class
);
$app->singleton(
    Illuminate\Contracts\Console\Kernel::class,
    App\Console\Kernel::class
);
$app->singleton(
    Illuminate\Contracts\Debug\ExceptionHandler::class,
    App\Exceptions\Handler::class
);
return $app;

アプリケーションクラスをインスタンス化し、singletonメソッドでフレームワークを使う準備をサービスコンテナに登録している
[singleton・サービスコンテナ]https://qiita.com/kd9951/items/f2157607d2f6a9534449

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

アプリケーションクラスのmakeメソッドを使用し、app.phpでサービスコンテナに登録したIlluminate\Contracts\Http\Kernel::class(httpカーネル)を生成して、handleメソッドの引数Request::capture()を指定して、HTTPリクエストからRequestを生成し、アプリ実行->実行後レスポンスを返す。

httpカーネルでは、主にアプリの準備やミドルウェア設定を行う。
handleメソッドの中のresponse = this->sendRequestThroughRouter($request)は受け取ったリクエストをルータに渡すことで、routes/web.phpのルートに沿った処理をしてくれる。また、返り値をRessponseまたはJsonResponseのインスタンスに変更している。

index.phpに戻って

$response->send();

アプリ実行後のレスポンスを返す。

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

終了処理 セッションデータの格納などを行う
[terminate]https://readouble.com/laravel/5.3/ja/middleware.html

[補足]

・クラスローダ
一つのサーバーにバージョンの違うライブラリを使用している二つのアプリがあるとして、ライブラリに互換性がない場合、片方が動けば、片方が動かない場合があるとする。クラスローダはロード(読み込んだクラス)を管理する。
階層関係のクラスローダの中のあるクラスローダがクラスをロードしようとしたときは、必ず親(祖先)のクラスローダによってすでにロードされているクラスが存在しないかチェックする、そして、該当するクラスが存在しない場合のみ、自身でロードを行うようになっている。並列関係にあるクラスローダ同士は、まったく独立の関係にあり、たとえ同じクラスがロードされたとしても、一切関与しないため、どちらのアプリも動くことができる。

[クラスローダー名]https://qiita.com/ArimaRyunosuke/items/c706bf314536f1f034ac