広告

【Laravel】ファサードの作成と実践・検証

Laravel

当サイトではアフィリエイト広告を利用しています。

広告

はじめに

Laravelのファサードを作成する手順をまとめました。
Laravelを使用する上で、避けては通れないほど重要な機能の一つです。

Laravelは標準で色々なファサードを用意しており、知らず知らずのうちにコーディングで使用していると思います。

実際に独自のファサードを作成し、使い方もまとめましたので、実践に役立つと思います。

Laravel Sailでの開発環境の構築方法は以下をご覧ください。

Windows
Laravel Sailで開発環境構築【Vite対応】
今回は、Laravel Sailを使って環境の構築を行いました。 SailはDockerですので、開発環境を簡単に用意することもできますし、カスタマイズすることも楽です。
Mac
【M1 Mac】Laravel Sailで開発環境構築【Vite対応】
Laravel Sailを使って環境の構築を行いました。 SailはDockerですので、開発環境を簡単に用意することもできますし、カスタマイズすることも楽です。
使用するバージョン
  • Windows 11 or macOS Monterey (M1)
  • Laravel Framework 8 or 9 or 10

2022/10/02 WindowsとMacを使い、最新バージョンで確認しました。
2023/03/11 Laravel10で確認しました。

他にも私のブログで、Laravelについて解説している記事がありますのでご覧ください。

広告

【紹介】個人開発

私の個人開発ですがQuiphaというサービスを開発しました。(Laravel, Vue3など)
良かったら、会員登録して動作を試してみて下さい。

また、Laravel 9 実践入門という書籍を出版しました。
Kindle Unlimitedを契約している方であれば、読み放題で無料でご覧いただくことができます

是非多くの方に読んでいただき、Laravelの開発に少しでもお役に立てたら幸いです。

ファサードのメリット

一番分かりやすいメリットとしては、自分でインスタンスを生成しなくても使える点でしょう。

// インスタンスを手動で作成
$book = new Book();
$book->getBook(1);

// インスタンスをnewせずに取得
\Book::getBook(1);

また、Laravelのファサードは、モックするための便利な方法が提供されているため、テストを行う際にも役立ちます。

それだけ?と思うかも知れませんが、あまり深く考えずに、ビジネスロジックや共通処理など、役割ごとにクラスを作成し、ファサードを介して取得するようにしておけば、良いのではないでしょうか。

サービスクラスの作成

今回は、ビジネスロジックを想定し、サービスクラスとして作成しますが、クラスであれば何でも良いです。

Servicesフォルダを作成しました。

app\Services\

上記のフォルダに以下のような簡単なクラスを作成しました。

app\Services\BookService.php
<?php

namespace App\Services;

/**
 * Book Service
 */
class BookService
{

    /**
     * get book
     * 
     * @param string $book_no no
     */
    public function getBook($book_no)
    {
        return "get book: " . $book_no;
    }
}

サービスプロバイダーの作成

クラスをサービスコンテナに登録します。以下のコマンドで、サービスプロバイダーを作成します。

$ sail php artisan make:provider BookServiceProvider

ファイルが作成されました。

app\Providers\BookServiceProvider.php

<?php

namespace App\Providers;

use Illuminate\Support\ServiceProvider;

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

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

registerメソッドの中で、サービスコンテナへの登録を行います。
名前とクラスパスでサービスコンテナに登録することができます。

    /**
     * Register services.
     *
     * @return void
     */
    public function register()
    {
        $this->app->bind('book', 'App\Services\BookService');
    }

サービスプロバイダーの登録

configファイルを開きましょう。

config\app.php

先ほど作成したサービスプロバイダーをconfigに追加します。

    'providers' => [
...
        App\Providers\BookServiceProvider::class,
    ],

これによりサービスプロバイダーが読み込まれます。

今回はファサードを介して取得するので関係ありませんが、この時点でサービスコンテナからインスタンスを取得することができます。

    $bookService = app()->make('book');
    $book = $bookService->getBook(1);
    echo $book; // get book: 1

ファサードの作成

ファサードを作成します。Facadesフォルダを作成しました。

app\Facades\

サービスプロバイダーの、サービスコンテナーに指定した名前を戻り値に指定します。

app\Facades\Book.php
<?php

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

class Book extends Facade
{

    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'book';
    }
}

これでファサードを介してインスタンスを取得する準備ができました。

エイリアスの登録

エイリアスに登録しましょう。configファイルを開きます。

config\app.php

    'aliases' => [
...
        'Book' => App\Facades\Book::class,
    ],

これにより、長いクラスのパスを毎回指定しなくて済みます
例えばuseに指定しなくても、バックスラッシュだけでFacadeにアクセスできるようになります。

\Book

ファサードを使ってみる

ファサードを介して、サービスクラスのインスタンスを取得してみます。
エイリアスに登録したため、useに宣言は不要で、以下のようにファサードを使用することができます。

    $book = \Book::getBook(1);
    echo $book; // get book

newを使用して、インスタンスを生成する必要がありません。
また、::でメソッドを呼んでいますが、静的メソッドではなく、インスタンスメソッドが呼ばれています。

VS Codeで確認

エイリアスについては、別記事で詳細にまとめていますので、こちらをご覧ください。
今回は以下の手順を行い、自作のファサードがVS Code上でエラーにならないか確認しましょう。

【Laravel】エイリアスをVS Codeでエラー解消・ジャンプ・補完
Laravelではエイリアスという便利な機能がありますが、開発時のIDEで問題があります。その解決方法をまとめました。

対応する前は、VS Code上でソースを確認するとエラー表示になっていました。
ちなみに、ソース上ではこのようになっていますが、実際は問題なく実行できます

以下のコマンドで、定義を最新化します。

$ sail php artisan ide-helper:generate

VS Code上で、エラーもなく、PHPDocも正常に表示され、自作した関数へジャンプすることができました。

広告

ファサードのモック

ファサードのメリットの一つとして、ファサードへの呼び出しをモックできます。

先程と同様、通常の実行を見てみましょう。

    $book = \Book::getBook(1);
    echo $book; // get book: 1

それでは、getBookメソッドの呼び出しをモックしてみましょう。
もとのクラスは全く変更しておりません。shouldReceiveとandReturnを使用するだけで、getBookの戻り値を変更することができました。

    \Book::shouldReceive('getBook')->andReturn('test code!');
    $book = \Book::getBook(1);
    echo $book; // test code!

ファサードのモックは、テストを行う際に便利です。

Laravelのモックについては、以下を参考ください。

10.x モック Laravel

ファサードを介して取得するインスタンスはシングルトン?

検証

ここからは色々と検証してみます。

インスタンスの挙動を試すために、クラス内に変数の追加と、getter/setterを追加しました。

<?php

namespace App\Services;

/**
 * Book Service
 */
class BookService
{
    var $book_name = "default name";

    /**
     * get book name
     * 
     * @return string book name
     */
    public function getBookName()
    {
        return $this->book_name;
    }

    /**
     * set book name
     * 
     * @param string $name name
     */
    public function setBookName($name)
    {
        $this->book_name = $name;
    }

    /**
     * get book
     * 
     * @param string $book_no no
     */
    public function getBook($book_no)
    {
        return "get book: " . $book_no;
    }
}

サービスコンテナの確認

サービスコンテナには、「$this->app->bind()」で登録しました。
これはサービスコンテナから取得する度に、新しいインスタンスが取得されます。

    $bookService = app()->make('book');
    echo spl_object_id($bookService); // インスタンスID: 282
    $bookService->setBookName("laravel");
    echo $bookService->getBookName(); // laravel

    // もう一度取得すると、別インスタンスで取得される
    $bookService = app()->make('book');
    echo spl_object_id($bookService); // インスタンスID: 289
    echo $bookService->getBookName(); // default name

今度は、サービスコンテナにシングルトンで登録してみます。

$this->app->singleton('book', 'App\Services\BookService');

試してみると、同じインスタンスが取得できました。

    $bookService = app()->make('book');
    echo spl_object_id($bookService); // インスタンスID: 282
    $bookService->setBookName("laravel");
    echo $bookService->getBookName(); // laravel

    // もう一度取得すると、同じインスタンスが取得される
    $bookService = app()->make('book');
    echo spl_object_id($bookService); // インスタンスID: 282
    echo $bookService->getBookName(); // laravel

ここまでは想定通りの動きです。

ファサードの確認

では、サービスコンテナには、「$this->app->bind()」で登録した場合、ファサードを介して取得するインスタンスは毎回変わるのでしょうか。

以下のコードで試してみました。

    \Book::setBookName("laravel");
    echo \Book::getBookName(); // laravel

上記のことから、ファサードを介して取得できるインスタンスは毎回同じようです。
(シングルトンのような挙動)

需要があるかどうかは別として、ファサードを介して新しいインスタンスを取得するにはどうすればよいでしょうか。
ファサードクラスに、リフレッシュを行う関数を作成しました。

app\Facades\Book.php

<?php

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

class Book extends Facade
{

    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor()
    {
        return 'book';
    }

    /**
     * refresh
     */
    public static function refresh()
    {
        static::clearResolvedInstance(static::getFacadeAccessor());
    }
}

refresh関数を呼ぶことで、新しいインスタンスを取得できることが確認できました。

    \Book::setBookName("laravel");
    echo \Book::getBookName(); // laravel
    
    // インスタンスをリフレッシュ
    \Book::refresh();
    // 新しいインスタンスを取得
    echo \Book::getBookName(); // default name

その他

初学者へ

Laravelを初めて触る方へ向け、手順やアドバイスをまとめました。

外部サーバーへ公開

作成したアプリは公開して使ってもらいましょう!
Laravelアプリケーションを外部公開する方法をまとめました。

脆弱性対策

脆弱性を抱えたアプリケーションの場合、攻撃を受ける可能性があり大変危険です。
作成したアプリケーションは、脆弱性対策も意識しましょう。

GitHubと連携

GitHubと連携する方法を解説しました。
プロジェクトの管理はGitHubを活用しましょう。

GitHub Copilot

GitHub Copilotを導入し、AIにコーディングをサポートしてもらうこともできます。

さいごに

今回は、Laravelのファサードを作成する手順をまとめました。
Laravelは色々と便利な機能や仕組みを提供していますので、是非理解して活用しましょう。

他にも私のブログで、Laravelについて解説している記事がありますのでご覧ください。

LaravelMacOSPHPWindowsプログラミング
広告

個人開発

千草 @chigusaweb

現役のITエンジニア。 気ままにコードを書いたり技術情報を発信しています。 Webアプリ/Windows・Macアプリ/モバイルアプリなど。 (Java, PHP, Javascript, Swift, Python, C#, 他) 個人開発:Clibor, Quipha, TXT-Crypter, 符計算特訓, チグサツール Kindle本: Laravel9 実践入門, 他

クリップボード履歴

Clibor

Windows

Cliborはシンプルで高機能なクリップボード履歴ソフトです。
また普段よく使うワードを定型文として登録し、いつでもクリップボードに保存することができます。高度なテキスト整形・FIFOモード・ホットキーに対応。

クリップボード履歴

Windows版Cliborの利便性を、そのままMacでも。
定型文登録、高度なテキスト整形、FIFOモードなど、便利なクリップボード履歴機能を利用できます。macOS最新のTahoeにも対応。

テキスト暗号化

テキストを暗号化してURLで共有・保存できる無料サービスです。
パスフレーズを知る人だけが復号できます。登録不要、データはサーバーに保存されません。
Notionでも利用できます。

学習

Quipha

Web / iOS

自分だけの問題集や問題を作成し、クイズを行い、学習に活用することができるアプリです。
例えば、学校の授業、語学学習、IT資格やその他の資格など多彩な分野での学習を支援します。
いつでも、どこでも、あなたの学習をサポート。

ツール

日常の「ちょっとした効率化」をサポートするWeb便利ツール集。
テキスト・データ処理から最新のAI連携まで、日々のちょっとした手間でググりがちなユーティリティを1つの場所に集約。

麻雀

麻雀の符計算をひたすら特訓しマスターしましょう。
初心者の方はもちろん、もっと速く計算したい方にも役立ちます。
5万対局以上の実践から問題を収録。

コメント

タイトルとURLをコピーしました