LoginSignup
12
20

More than 3 years have passed since last update.

LaravelのFacadeの作り方

Last updated at Posted at 2019-10-18

手順

1.インスタンス生成対象のクラス作成
2.サービスプロバイダーの登録・使用
 (A)AppServiceProviderを使用する
 (B)そのクラス用のサービスプロバイダーを作成し、config/app.phpに登録
3.インスタンス生成方法を記載
 (A)AppServiceProviderクラスに記載
 (B)作成したサービスプロバイダーに記載
4.Facadeクラスを作成
5.Facadeを使用する
6.Facadeのエイリアスを張る
7.まとめ

1.インスタンス生成対象のクラス作成

Eatクラスを作成してみる。

<?php

namespace App\Services;

class Eat
{
    public function eat(string $food) {
        echo $food.'を食べる。';
   }
}

Eatクラスは「◯◯を食べる」を表示するeatメソッドのみが実装されている。
◯◯に当たる部分は、eatメソッドを使う際に挿入し、それが表示結果に反映されるようにする。


$instance = new Eat();
echo $instance->eat('ばなな');

->ばななを食べる

2.サービスプロバイダーの登録・使用

(A)AppServiceProviderを使用する

AppServiceProviderを使用する場合は、ここでは特に何も行う必要はありません。
初期では以下の様になっています。


<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

(B)そのクラス用のサービスプロバイダーを作成し、config/app.phpに登録

ここでは、Eatクラスと対応するEatServiceProviderクラスを作成。

Laravelでは以下の様に作成コマンドが用意されていますので、そちらを使います。

php artisan make:provider EatServiceProvider

上記コマンドで以下のようなEatServiceProviderクラスが新たに生成されました。
初期では以下の様になっています。

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

class EatServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        //
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

上記で出来上がったEatServiceProviderを登録ていきます。

今回のプロジェクトで新規で追加するものをわかりやすくするために、コメントで新規追加と入れておきます。

config/app.php
<?php

return [
    '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,
        Illuminate\Filesystem\FilesystemServiceProvider::class,
        Illuminate\Foundation\Providers\FoundationServiceProvider::class,
        Illuminate\Hashing\HashServiceProvider::class,
        Illuminate\Mail\MailServiceProvider::class,
        Illuminate\Notifications\NotificationServiceProvider::class,
        Illuminate\Pagination\PaginationServiceProvider::class,
        Illuminate\Pipeline\PipelineServiceProvider::class,
        Illuminate\Queue\QueueServiceProvider::class,
        Illuminate\Redis\RedisServiceProvider::class,
        Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
        Illuminate\Session\SessionServiceProvider::class,
        Illuminate\Translation\TranslationServiceProvider::class,
        Illuminate\Validation\ValidationServiceProvider::class,
        Illuminate\View\ViewServiceProvider::class,

        /*
         * Package Service Providers...
         */

        /*
         * Application Service Providers...
         */
        App\Providers\AppServiceProvider::class,
        App\Providers\AuthServiceProvider::class,
        // App\Providers\BroadcastServiceProvider::class,
        App\Providers\EventServiceProvider::class,
        App\Providers\MacroServiceProvider::class,
        App\Providers\RouteServiceProvider::class,

        /**
         * 新規追加
         */
        App\Providers\EatServiceProvider::class, <= ここに追加しました
    ],
];

これで「(A)AppServiceProviderを使用する」|「(B)そのクラス用のサービスプロバイダーを作成し、config/app.phpに登録」共にインスタンス生成の方法を記載する準備が整いました。

3.インスタンス生成方法を記載

(A)AppServiceProviderクラスに記載

実際に登録していきます。


<?php

namespace App\Providers;

use App\Services\Eat;
use Illuminate\Support\ServiceProvider;

class AppServiceProvider extends ServiceProvider
{
    /**
     * Register any application services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('eat', function () {
            return new Eat();
        });
    }

    /**
     * Bootstrap any application services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

今回は、eatというサービスコンテナの結合名でApp\Services\Eat.phpのインスタンスを返しました。
仮に、eatというサービスコンテナの結合名で他のオブジェクトのインスタンスを返したくなれば、newするクラスを変えるだけで良いのです!

(B)作成したサービスプロバイダーに記載

こちらも3(A)同様に登録していきます。

<?php

namespace App\Providers;

use App\Services\Eat;
use Illuminate\Support\ServiceProvider;

class EatServiceProvider extends ServiceProvider
{
    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->singleton('eat', function () {
            return new Eat();
        });
    }

    /**
     * Bootstrap services.
     *
     * @return void
     */
    public function boot()
    {
        //
    }
}

こちらも、3(A)同様にeatというサービスコンテナの結合名でApp\Services\Eat.phpのインスタンスを返しました。

4.Facadeクラスを作成

こちらは、コマンド等ございませんので、自分で一から作成する形になります。
今回は、App\Facadesディレクトリを作成し、そこにEatファサードクラスを設置したいと思います。

<?php

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

class Eat extends Facade
{
    protected static function getFacadeAccessor()
    {
        return 'eat';
    }
}

Facadeは、getFacadeAccessorの返り値と一致するサービスコンテナの結合名を探し、あればその結合名で登録されているインスタンスと紐づくというものです。

今回の場合、EatファサードApp\Services\Eat.phpのインスタンスと紐付けたいため、App\Services\Eat.phpのインスタンスを返すように登録されている、サービスコンテナ内の結合名を探すと、先程、2(A)+3(A) or 2(B)+3(B)で登録したeatキーがありますね。

これをEatファサードのgetFacadeAccessorの返り値として、返せばひも付きができますので、今回はeatという文字列を返します。

5.Facadeを使用する

では、1~4で準備・作成を行ったEatファサードを実際に使ってみましょう。
まず、phpファイルでファサードを使用します。
今回は、main.phpでEatファサードを下記のように使用してみます。

main.php

App\Facades\Eat::eat('ばなな');

次にconsole上でmain.phpを実行してみます。

php main.php

→ ばななを食べる

りんごに変えて実行してみます。

main.php
App\Facades\Eat::eat('りんご');
php main.php

→ りんごを食べる

この様にEatファサード経由でApp\Services\Eat.phpeatメソッドを使用できるようになりました。

6.Facadeのエイリアスを張る

1~5で完成でもいいのですが、Eatファサードを使用する度に、毎回フルパスでApp\Facades\Eatと書いたり、useしたりするのも若干冗長な気がしますので、今回作成したEatファサードエイリアスを張って、より簡易にアクセスできるようにしていきたいと思います。

今回は、EatファサードのエイリアスEatを登録してきます。
今回のプロジェクトで新規で追加するものをわかりやすくするために、コメントで新規追加と入れておきます。

config/app.php
<?php

return [

    /*
    |--------------------------------------------------------------------------
    | Class Aliases
    |--------------------------------------------------------------------------
    |
    | This array of class aliases will be registered when this application
    | is started. However, feel free to register as many as you wish as
    | the aliases are "lazy" loaded so they don't hinder performance.
    |
    */

    '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,
        'DB' => Illuminate\Support\Facades\DB::class,
        'Eloquent' => Illuminate\Database\Eloquent\Model::class,
        'Event' => Illuminate\Support\Facades\Event::class,
        'File' => Illuminate\Support\Facades\File::class,
        'Gate' => Illuminate\Support\Facades\Gate::class,
        'Hash' => Illuminate\Support\Facades\Hash::class,
        'Lang' => Illuminate\Support\Facades\Lang::class,
        'Log' => Illuminate\Support\Facades\Log::class,
        'Mail' => Illuminate\Support\Facades\Mail::class,
        'Notification' => Illuminate\Support\Facades\Notification::class,
        'Password' => Illuminate\Support\Facades\Password::class,
        'Queue' => Illuminate\Support\Facades\Queue::class,
        'Redirect' => Illuminate\Support\Facades\Redirect::class,
        'Redis' => Illuminate\Support\Facades\Redis::class,
        'Request' => Illuminate\Support\Facades\Request::class,
        'Response' => Illuminate\Support\Facades\Response::class,
        'Route' => Illuminate\Support\Facades\Route::class,
        'Schema' => Illuminate\Support\Facades\Schema::class,
        'Session' => Illuminate\Support\Facades\Session::class,
        'Storage' => Illuminate\Support\Facades\Storage::class,
        'Str' => Illuminate\Support\Str::class,
        'URL' => Illuminate\Support\Facades\URL::class,
        'Validator' => Illuminate\Support\Facades\Validator::class,
        'View' => Illuminate\Support\Facades\View::class,

        /**
         * 新規追加
         */
        'Eat' => App\Facades\Eat::class, <= ここに追加しました
    ],
];

登録したエイリアスEatEatファサードにアクセスできるか試してみます。

main.php
Eat::eat('ばなな');
php main.php

表示結果
ばななを食べる。」

7.まとめ

1~6で新規でFacadeを作成し、使用することが可能になりました。
実際問題、Facadeを新規で作成することはさほど多くないように思えますが、新規で作成してみることで、Facadeへの見解が深まり、ライブラリ等が既存で用意しているようなFacadeを使用する際や、プログラムの設計時に役立つこともありましたので、いい勉強になったかなと思います。

疑問点や指摘等ございましたら、ぜひお願い致します。

12
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
12
20