Laravel 9.x ファサード

イントロダクション

Laravelのドキュメント全体を通して、「ファサード」を介してLaravelの機能を操作するコード例を紹介しています。ファサードは、アプリケーションのサービスコンテナで使用可能なクラスに対して「静的な」インターフェイスを提供します。Laravelは、Laravelのほとんどすべての機能へのアクセスを提供する多くのファサードを提供しています。

Laravelファサードは、サービスコンテナ内の基礎となるクラスへの「静的プロキシ」として機能し、従来の静的メソッドよりもテスト容易性と柔軟性を維持しながら、簡潔で表現力豊かな構文という利点を提供しています。ファサードが内部でどのように機能するかを完全に理解していなくても、まったく問題ありません。流れに沿って、Laravelについて学び続けてください。

Laravelのファサードはすべて、Illuminate\Support\Facades名前空間で定義します。したがって、次のようなファサードに簡単にアクセスできます。

use Illuminate\Support\Facades\Cache;
use Illuminate\Support\Facades\Route;

Route::get('/cache', function () {
    return Cache::get('key');
});

Laravelのドキュメント全体を通じ、コード例の多くでファサードを使用して、フレームワークのさまざまな機能を紹介しています。

ヘルパ関数

ファサードを補完するため、Laravelはさまざまなグローバルな「ヘルパ機能」を提供し、Laravel機能の一般的な操作をより簡単にしています。使用する可能性のある一般的なヘルパ関数には、viewresponseurlconfigなどがあります。Laravelが提供する各ヘルパ機能は、対応する機能とともにドキュメント化しています。関数の完全なリストは、専用のヘルパドキュメント内にあります。

たとえば、Illuminate\Support\Facades\Responseファサードを使用してJSONレスポンスを生成する代わりに、単にresponse関数を使用することもできます。ヘルパ関数はグローバルに利用できるため、使用するためにクラスをインポートする必要はありません。

use Illuminate\Support\Facades\Response;

Route::get('/users', function () {
    return Response::json([
        // ...
    ]);
});

Route::get('/users', function () {
    return response()->json([
        // ...
    ]);
});

いつファサードを使うか

ファサードには多くの利点があります。これらは、手作業で挿入または設定する必要のある長いクラス名を覚えていなくても、Laravelの機能を使用できるようにする簡潔で覚えやすい構文を提供しています。さらに、PHPの動的メソッドを独自に使用しているため、テストが簡単です。

ただし、ファサードを使用する場合は注意が必要です。ファサードの主な危険性は、クラスの「スコープクリープ」です。ファサードは非常に使いやすく、依存注入を必要としないため、1つのクラスで多くのファサードを使用するのは簡単で、クラスを成長させ続けてしまいがちです。依存注入を使用していれば、大きなコンストラクタによりクラスが大きくなりすぎていることを示す視覚的なフィードバックにより、これが起きる可能性は低減されます。したがって、ファサードを使用するときは、クラスのサイズに特に注意して、クラスの責任範囲が狭くなるようにしてください。クラスが大きくなりすぎている場合は、クラスを複数の小さなクラスに分割することを検討してください。

ファサード対依存注入

依存注入の主な利点の1つは、注入するクラスの実装を交換できることです。これは、モックまたはスタブを挿入して、さまざまなメソッドがスタブで呼び出されたことを表明できるため、テスト中に役立ちます。

通常、真に静的なクラスメソッドをモックまたはスタブすることはできません。ただし、ファサードは動的メソッドを使用して、サービスコンテナが解決するオブジェクトへのメソッド呼び出しをプロキシするため、挿入するクラスインスタンスをテストするのと同様に、実際にはファサードをテストできます。たとえば、次のルートがあるとします。

use Illuminate\Support\Facades\Cache;

Route::get('/cache', function () {
    return Cache::get('key');
});

Laravelのファサードテストメソッドを使用して、次のテストを記述し、期待する引数でCache::getメソッドを呼び出すことを確認できます。

use Illuminate\Support\Facades\Cache;

/**
 * 基本的な機能テストの例
 *
 * @return void
 */
public function testBasicExample()
{
    Cache::shouldReceive('get')
         ->with('key')
         ->andReturn('value');

    $response = $this->get('/cache');

    $response->assertSee('value');
}

ファサード対ヘルパ関数

Laravelには、ファサードに加えて、ビューの生成、イベントの発生、ジョブのディスパッチ、HTTP応答の送信などの一般的なタスクを実行できるさまざまな「ヘルパ」関数が含まれています。これらのヘルパ関数の多くは、対応するファサードと同じ機能を実行します。たとえば、このファサード呼び出しとヘルパ呼び出しは同等です。

return Illuminate\Support\Facades\View::make('profile');

return view('profile');

ファサードとヘルパ機能の間に実際的な違いはまったくありません。ヘルパ関数を使用する場合でも、対応するファサードとまったく同じようにテストできます。たとえば、次のルートがあるとします。

Route::get('/cache', function () {
    return cache('key');
});

内部的には、cacheヘルパはCacheファサードの基礎となるクラスでgetメソッドを呼び出します。したがって、ヘルパ関数を使用している場合でも、次のテストを記述して、期待した引数でメソッドが呼び出されたことを確認できます。

use Illuminate\Support\Facades\Cache;

/**
 * 基本的な機能テストの例
 *
 * @return void
 */
public function testBasicExample()
{
    Cache::shouldReceive('get')
         ->with('key')
         ->andReturn('value');

    $response = $this->get('/cache');

    $response->assertSee('value');
}

ファサードの仕組み

Laravelアプリケーションのファサードは、コンテナからのオブジェクトに対するアクセスを提供するクラスです。この作業を行うメカニズムは、Facadeクラスにあります。Laravelのファサード、および作成したカスタムファサードは、基本のIlluminate\Support\Facades\Facadeクラスを拡張します。

Facade基本クラスは__callStatic()マジックメソッドを利用して、ファサードへの呼び出しをコンテナが解決するオブジェクトへの呼び出しへと延期します。下の例では、Laravelキャッシュシステムが呼び出されます。このコードを一瞥すると、静的なgetメソッドがCacheクラスで呼び出されていると思われるかもしれません。

<?php

namespace App\Http\Controllers;

use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Cache;

class UserController extends Controller
{
    /**
     * 特定のユーザーのプロファイルを表示
     *
     * @param  int  $id
     * @return Response
     */
    public function showProfile($id)
    {
        $user = Cache::get('user:'.$id);

        return view('profile', ['user' => $user]);
    }
}

ファイルの上部近くで、Cacheファサードを「インポート」していることに注意してください。このファサードは、Illuminate\Contracts\Cache\Factoryインターフェイスの基盤となる実装にアクセスするためのプロキシとして機能します。ファサードを使用して行う呼び出しはすべて、Laravelのキャッシュサービスの基盤となるインスタンスに渡されます。

そのIlluminate\Support\Facades\Cacheクラスを見ると、静的メソッドgetがないことがわかります。

class Cache extends Facade
{
    /**
     * コンポーネントの登録名を取得
     *
     * @return string
     */
    protected static function getFacadeAccessor() { return 'cache'; }
}

代わりに、Cacheファサードは基本のFacadeクラスを拡張し、メソッドgetFacadeAccessor()を定義します。このメソッドの仕事は、サービスコンテナ結合名を返すことです。ユーザーがCacheファサードの静的メソッドを参照すると、Laravelはサービスコンテナcache結合を依存解決し、リクエストされたメソッド(この場合はget)をそのオブジェクトに対して実行します。

リアルタイムファサード

リアルタイムファサードを使用すると、アプリケーション内の任意のクラスをファサードであるかのように扱うことができます。これをどのように使用できるかを説明するために、最初にリアルタイムファサードを使用しないコードを調べてみましょう。たとえば、Podcastモデルにpublishメソッドがあるとしましょう。ただし、ポッドキャストを公開するには、Publisherインスタンスを挿入する必要があります。

<?php

namespace App\Models;

use App\Contracts\Publisher;
use Illuminate\Database\Eloquent\Model;

class Podcast extends Model
{
    /**
     * ポッドキャストを公開
     *
     * @param  Publisher  $publisher
     * @return void
     */
    public function publish(Publisher $publisher)
    {
        $this->update(['publishing' => now()]);

        $publisher->publish($this);
    }
}

パブリッシャーの実装をメソッドに注入すると、注入されたパブリッシャーをモックできるため、メソッドを分離して簡単にテストできます。ただし、publishメソッドを呼び出すたびに、常にパブリッシャーインスタンスを渡す必要があります。リアルタイムのファサードを使用すると、Publisherインスタンスを明示的に渡す必要がなく、同じテスト容易性を維持できます。リアルタイムのファサードを生成するには、インポートするクラスの名前空間の前にFacadesを付けます。

<?php

namespace App\Models;

use Facades\App\Contracts\Publisher;
use Illuminate\Database\Eloquent\Model;

class Podcast extends Model
{
    /**
     * ポッドキャストを公開
     *
     * @return void
     */
    public function publish()
    {
        $this->update(['publishing' => now()]);

        Publisher::publish($this);
    }
}

リアルタイムファサードを使用する場合、パブリッシャーの実装はFacadesプレフィックスの後に表示されるインターフェイスまたはクラス名の部分を使用してサービスコンテナが依存解決します。テスト時には、Laravelの組み込みファサードテストヘルパを使用して、このメソッド呼び出しをモックできます。

<?php

namespace Tests\Feature;

use App\Models\Podcast;
use Facades\App\Contracts\Publisher;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Tests\TestCase;

class PodcastTest extends TestCase
{
    use RefreshDatabase;

    /**
     * テスト例
     *
     * @return void
     */
    public function test_podcast_can_be_published()
    {
        $podcast = Podcast::factory()->create();

        Publisher::shouldReceive('publish')->once()->with($podcast);

        $podcast->publish();
    }
}

ファサードクラスリファレンス

以下に、すべてのファサードとその基礎となるクラスを示します。これは、特定のファサードルートのAPIドキュメントをすばやく掘り下げるための便利なツールです。該当するサービスコンテナ結合キーがある場合は内容に含めています。

ファサード クラス サービスコンテナ結合キー
App Illuminate\Foundation\Application app
Artisan Illuminate\Contracts\Console\Kernel artisan
Auth Illuminate\Auth\AuthManager auth
Auth (Instance) Illuminate\Contracts\Auth\Guard auth.driver
Blade Illuminate\View\Compilers\BladeCompiler blade.compiler
Broadcast Illuminate\Contracts\Broadcasting\Factory  
Broadcast (Instance) Illuminate\Contracts\Broadcasting\Broadcaster  
Bus Illuminate\Contracts\Bus\Dispatcher  
Cache Illuminate\Cache\CacheManager cache
Cache (Instance) Illuminate\Cache\Repository cache.store
Config Illuminate\Config\Repository config
Cookie Illuminate\Cookie\CookieJar cookie
Crypt Illuminate\Encryption\Encrypter encrypter
Date Illuminate\Support\DateFactory date
DB Illuminate\Database\DatabaseManager db
DB (Instance) Illuminate\Database\Connection db.connection
Event Illuminate\Events\Dispatcher events
File Illuminate\Filesystem\Filesystem files
Gate Illuminate\Contracts\Auth\Access\Gate  
Hash Illuminate\Contracts\Hashing\Hasher hash
Http Illuminate\Http\Client\Factory  
Lang Illuminate\Translation\Translator translator
Log Illuminate\Log\LogManager log
Mail Illuminate\Mail\Mailer mailer
Notification Illuminate\Notifications\ChannelManager  
Password Illuminate\Auth\Passwords\PasswordBrokerManager auth.password
Password (Instance) Illuminate\Auth\Passwords\PasswordBroker auth.password.broker
Queue Illuminate\Queue\QueueManager queue
Queue (Instance) Illuminate\Contracts\Queue\Queue queue.connection
Queue (Base Class) Illuminate\Queue\Queue  
Redirect Illuminate\Routing\Redirector redirect
Redis Illuminate\Redis\RedisManager redis
Redis (Instance) Illuminate\Redis\Connections\Connection redis.connection
Request Illuminate\Http\Request request
Response Illuminate\Contracts\Routing\ResponseFactory  
Response (Instance) Illuminate\Http\Response  
Route Illuminate\Routing\Router router
Schema Illuminate\Database\Schema\Builder  
Session Illuminate\Session\SessionManager session
Session (Instance) Illuminate\Session\Store session.store
Storage Illuminate\Filesystem\FilesystemManager filesystem
Storage (Instance) Illuminate\Contracts\Filesystem\Filesystem filesystem.disk
URL Illuminate\Routing\UrlGenerator url
Validator Illuminate\Validation\Factory validator
Validator (Instance) Illuminate\Validation\Validator  
View Illuminate\View\Factory view
View (Instance) Illuminate\View\View  
Vite Illuminate\Foundation\Vite  

ドキュメント章別ページ

ヘッダー項目移動

注目:アイコン:ページ内リンク設置(リンクがないヘッダーへの移動では、リンクがある以前のヘッダーのハッシュをURLへ付加します。

移動

クリックで即時移動します。

設定

適用ボタンクリック後に、全項目まとめて適用されます。

カラーテーマ
和文指定 Pagination
和文指定 Scaffold
Largeスクリーン表示幅
インデント
本文フォント
コードフォント
フォント適用確認

フォントの指定フィールドから、フォーカスが外れると、当ブロックの内容に反映されます。EnglishのDisplayもPreviewしてください。

フォント設定時、表示に不具合が出た場合、当サイトのクッキーを削除してください。

バックスラッシュを含むインライン\Code\Blockの例です。

以下はコードブロックの例です。

<?php

namespace App;

use Illuminate\Database\Eloquent\Model;

class User extends Model
{
    /**
     * ユーザに関連する電話レコードを取得
     */
    public function phone()
    {
        return $this->hasOne('App\Phone');
    }
}

設定を保存する前に、表示が乱れないか必ず確認してください。CSSによるフォントファミリー指定の知識がない場合は、フォントを変更しないほうが良いでしょう。

キーボード・ショートカット

オープン操作

PDC

ページ(章)移動の左オフキャンバスオープン

HA

ヘッダー移動モーダルオープン

MS

移動/設定の右オフキャンバスオープン

ヘッダー移動

T

最初のヘッダーへ移動

E

最後のヘッダーへ移動

NJ

次ヘッダー(H2〜H4)へ移動

BK

前ヘッダー(H2〜H4)へ移動

その他

?

このヘルプページ表示
閉じる