Laravelのファサードを作ってみる
PHP フレームワークの基礎力を養うために、所属するチームのメンバーと一緒に Laravel の読書会を始めた。 先日ファサードに関する章を読んだが、理解度がいまいちだったので、簡単なファサードを作成して動かしてみた。
はじめに、文字列を返すだけのメソッドを持つ Greet クラスを app/Services/Greet.php
に用意する。
<?php namespace App\Services; class Greet { public function getGreet(string $name) { return 'Hello, ' . $name; } }
つぎに、Artisan コマンドを使ってサービスプロバイダを作成する。
この場合は app/Providers/GreetServiceProvider.php
が自動作成される。
$ php artisan make:provider GreetServiceProvider Provider created successfully.
<?php namespace App\Providers; use Illuminate\Support\ServiceProvider; class GreetServiceProvider extends ServiceProvider { /** * Register services. * * @return void */ public function register() { // } /** * Bootstrap services. * * @return void */ public function boot() { // } }
register メソッドを書き換えて、App\Services\Greet
クラスをサービスコンテナにバインドする。
public function register()
{
app()->singleton('greet', 'App\Services\Greet');
}
config/app.php
の providers プロパティに追記して、サービスプロバイダを定義する。
'providers' => [
// 省略
App\Providers\GreetServiceProvider::class,
],
同じ設定ファイルの aliases キーにファサードで利用するクラスを追加する。
'aliases' => [ // 省略 'Greet' => App\Facades\Greet::class, ],
app/Facades/Greet.php
に Facade クラスを作成する。Illuminate\Support\Facades\Facade
を継承することで、実装されていないクラスメソッドが呼ばれた場合は、スーパークラスの __callStatic
というマジックメソッドを経由して、サービスコンテナから取得したインスタンスに対してメソッド実行してくれる。
<?php namespace App\Facades; use Illuminate\Support\Facades\Facade; class Greet extends Facade { protected static function getFacadeAccessor() { return 'greet'; } }
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); }
ファサードを利用して文字列を取得できた 🙌
echo Greet::getGreet('Goodbye'); // Hello, Goodbye
ファサードの処理の流れをイメージできた気がする。引き続きみんなで読書していきます 🚀