kmmkの雑種系日記

学習まとめです。

PHPフレームワーク Laravel webアプリケーション2章自分なりのまとめ

ライフサイクル

基本的な流れは

request > public\index.php > app\Http\Kernel.php > Illuminate\Routing\Router\routers\web.php > ミドルウェア > コントローラ

レスポンスはこの流れの逆。

エントリポイント(index.php

  1. vendor配下のライブラリをすべて自動的にロードしてくれます。requireを書きまくることがなくなり楽になった(composer必要)
// 1 : オートローダーの読み込み
define('LARAVEL_START', microtime(true));
require __DIR__.'/../vendor/autoload.php';

// 2 : フレームワークの起動
$app = require_once __DIR__.'/../bootstrap/app.php';

// 3 : アプリケーションの実行
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
$response = $kernel->handle(
    $request = Illuminate\Http\Request::capture()
);

// 4 : HTTPレスポンスの送信
$response->send();

// 5 : 終了処理
$kernel->terminate($request, $response);

HTTPカーネル(app\Http\Kernel.php

内容

・アプリケーションのセットアップ

ミドルウェアの設定(App\Http\Kernel)

ルーターの実行(requestをルータに渡す。responseをエントリポイントに返す)

※ App\Http\Kernel ではミドルウェアの設定のみ記述。基底クラスは Illuminate\Foundation\Http\Kernelに書かれている

ルータ

内容

[Request] : 定義されたルートの中からRequestにマッチするルートを探して、処理を実行する

[Response] : コントローラー・ミドルウェアからレスポンスとして返される値をjson形式に変更して返す。

APIの場合はapi.phpで設定する

  1. getリクエスト / postリクエストなどに対する処理を記述

  2. returnにはviewファイル名を記述

Route::get('/', function () {
    return view('welcome');
});

ミドルウェア

内容

ルートで指定された処理の実行前後に任意の処理を実行可能

コントローラー

内容

・HTTPリクエストに対応する処理の実行

ビジネスロジックの実行

・データベースアクセスの実行

作成したController

class TaskController extends Controller
{
   public function getTasks(Request $request, TaskService $service)
   {
      // 1 HTTPリクエストの値を参照
      $isDone = $request->get('is_done');

      // 2 ビジネスロジックの実行
      $tasks = $service->findTasks($isDone);

      // 3 レスポンスの返却
      $return response($tasks);
   }
}

サービスコンテナ(バインドと解決)

複数のクラスが同じ機能のクラスを使い回す場合に、複雑になるのを防ぐ。 (インスタンス生成方法が登録されている)

クラスの一元管理をして、必要ならコンストラクタやメソッドの引数から注入する(DI)←ここまだ未熟。。理解しきれていない。

例)

1.バインド(サービスコンテナにインスタンス生成方法を登録)

2.解決(インスタンスの要求)

class Foo
{
   protected $foo1;

   public function __construct($foo1 = "foo")
   {
      $this->foo1 = $foo1
   }

}


// 1 バインド
app()->bind(Foo::class,function(Application $app){
   return new Foo($foo1);
}

// 2 解決
$foo = app()->make(Foo::class);

バインドの定義場所

場所:AppServiceProvider

register,bootの2つのメソッドが存在してるが、バインド処理はregisterに定義するのがいいっぽい。

App\Providers\AppServiceProvider

class AppServiceProvider extends ServiceProvider
{

    public function register()
    {
        // 1 バインド処理の定義
    }


    public function register()
    {
        // 
    }
}

まだ、コンストラクタインジェクションとメソッドインジェクションが理解しきれていない。。

ファサード

例)debugキーの取得

前提:Configクラスにgetメソッドはない

$debug = \Config::get('app.debug');

これが可能な理由Illuminate\Support\Facades\Config::classConfigという名前でエイリアスされている。

config/app.php(アプリケーションの起動処理でエイリアスが作成されている)

'aliases' => [

        'App' => Illuminate\Support\Facades\App::class,
        'Arr' => Illuminate\Support\Arr::class,
        'Artisan' => Illuminate\Support\Facades\Artisan::class,
        'Auth' => Illuminate\Support\Facades\Auth::class,
        'Blade' => Illuminate\Support\Facades\Blade::class,
        'Broadcast' => Illuminate\Support\Facades\Broadcast::class,
        'Bus' => Illuminate\Support\Facades\Bus::class,
        'Cache' => Illuminate\Support\Facades\Cache::class,
        'Config' => Illuminate\Support\Facades\Config::class,
        'Cookie' => Illuminate\Support\Facades\Cookie::class,
        'Crypt' => Illuminate\Support\Facades\Crypt::class,

継承元のFacadeクラスを見てみる

getメソッドはないが、呼ばれたクラスが実装されてない場合は__callStaticというマジックメソッドが実行される。

捜査対象のインスタンスを取得してメソッドの実行を行う。

public static function __callStatic($method, $args)
    {
        $instance = static::getFacadeRoot();

        if (! $instance) {
            throw new RuntimeException('A facade root has not been set.');
        }

        return $instance->$method(...$args);
    }
}

サービスプロバイダー

公式引用

サービスプロバイダ 5.3 Laravel

サービスコンテナの結合や、イベントリスナ、フィルター、それにルートなどを登録する。 config/app.phpでロードされるが、全てのリクエストで必ずロードされるとは限らず、そのプロバイダが提供するサービスが、実際に必要なときにのみロードされる「遅延」プロバイダ

役割

・サービスコンテナへのバインド

・イベントリスナー / ミドルウェア / ルーティングの登録

・外部コンポーネントの組み込み

config\app.php

'providers' => [

        /*
         * Laravel Framework Service Providers...
         */
        Illuminate\Auth\AuthServiceProvider::class,
        Illuminate\Broadcasting\BroadcastServiceProvider::class,
        Illuminate\Bus\BusServiceProvider::class,
        Illuminate\Cache\CacheServiceProvider::class,
        Illuminate\Foundation\Providers\ConsoleSupportServiceProvider::class,
        Illuminate\Cookie\CookieServiceProvider::class,
        Illuminate\Database\DatabaseServiceProvider::class,
        Illuminate\Encryption\EncryptionServiceProvider::class,
        :
]

cacheという名前でCacheManagerのインスタンスをシングルトンでバインドしてみる

Illuminate\Cache\ServiceProvider

public function register()
{
   $this->app->singlton('cache',function($app){
      return new CacheManager($app);   
   }};
}

プロバイダの作成

app/providerに作成される

php artisan make:provider *provider_name*

laravel楽しいけどむずい。。