はじめに

Laravelのドキュメント全体を通して、Laravelの機能と対話するコードの例が「ファサード」を介して示されています。ファサードは、アプリケーションのサービスコンテナで利用可能なクラスへの「静的」インターフェースを提供します。Laravelには、ほぼすべてのLaravelの機能にアクセスするための多くのファサードが付属しています。

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

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

  1. use Illuminate\Support\Facades\Cache;
  2. use Illuminate\Support\Facades\Route;
  3. Route::get('/cache', function () {
  4. return Cache::get('key');
  5. });

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

ヘルパー関数

ファサードを補完するために、Laravelは一般的なLaravelの機能と対話するのをさらに簡単にするさまざまなグローバル「ヘルパー関数」を提供しています。一般的に使用されるヘルパー関数には、viewresponseurlconfigなどがあります。Laravelが提供する各ヘルパー関数は、それに対応する機能とともに文書化されています。ただし、完全なリストは専用のヘルパー文書内で利用可能です。

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

  1. use Illuminate\Support\Facades\Response;
  2. Route::get('/users', function () {
  3. return Response::json([
  4. // ...
  5. ]);
  6. });
  7. Route::get('/users', function () {
  8. return response()->json([
  9. // ...
  10. ]);
  11. });

ファサードを利用するタイミング

ファサードには多くの利点があります。ファサードは、長いクラス名を記憶することなくLaravelの機能を使用できる簡潔で記憶に残る構文を提供します。さらに、PHPの動的メソッドの独自の使用により、テストが容易です。

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

ファサードと依存性注入

依存性注入の主な利点の1つは、注入されたクラスの実装を入れ替える能力です。これはテスト中に便利で、モックやスタブを注入し、さまざまなメソッドがスタブで呼び出されたことを確認できます。

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

  1. use Illuminate\Support\Facades\Cache;
  2. Route::get('/cache', function () {
  3. return Cache::get('key');
  4. });

Laravelのファサードテストメソッドを使用して、Cache::getメソッドが期待した引数で呼び出されたことを確認するために、次のテストを書くことができます:

  1. use Illuminate\Support\Facades\Cache;
  2. test('basic example', function () {
  3. Cache::shouldReceive('get')
  4. ->with('key')
  5. ->andReturn('value');
  6. $response = $this->get('/cache');
  7. $response->assertSee('value');
  8. });
  1. use Illuminate\Support\Facades\Cache;
  2. /**
  3. * A basic functional test example.
  4. */
  5. public function test_basic_example(): void
  6. {
  7. Cache::shouldReceive('get')
  8. ->with('key')
  9. ->andReturn('value');
  10. $response = $this->get('/cache');
  11. $response->assertSee('value');
  12. }

ファサードとヘルパー関数

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

  1. return Illuminate\Support\Facades\View::make('profile');
  2. return view('profile');

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

  1. Route::get('/cache', function () {
  2. return cache('key');
  3. });
  1. ``````php
  2. use Illuminate\Support\Facades\Cache;
  3. /**
  4. * A basic functional test example.
  5. */
  6. public function test_basic_example(): void
  7. {
  8. Cache::shouldReceive('get')
  9. ->with('key')
  10. ->andReturn('value');
  11. $response = $this->get('/cache');
  12. $response->assertSee('value');
  13. }
  14. `

ファサードの仕組み

Laravelアプリケーションにおいて、ファサードはコンテナからオブジェクトへのアクセスを提供するクラスです。この仕組みを実現するための機構はFacadeクラスにあります。Laravelのファサードと、あなたが作成するカスタムファサードは、基本のIlluminate\Support\Facades\Facadeクラスを拡張します。

  1. ``````php
  2. <?php
  3. namespace App\Http\Controllers;
  4. use App\Http\Controllers\Controller;
  5. use Illuminate\Support\Facades\Cache;
  6. use Illuminate\View\View;
  7. class UserController extends Controller
  8. {
  9. /**
  10. * Show the profile for the given user.
  11. */
  12. public function showProfile(string $id): View
  13. {
  14. $user = Cache::get('user:'.$id);
  15. return view('profile', ['user' => $user]);
  16. }
  17. }
  18. `

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

  1. ``````php
  2. class Cache extends Facade
  3. {
  4. /**
  5. * Get the registered name of the component.
  6. */
  7. protected static function getFacadeAccessor(): string
  8. {
  9. return 'cache';
  10. }
  11. }
  12. `

代わりに、Cacheファサードは基本のFacadeクラスを拡張し、getFacadeAccessor()メソッドを定義します。このメソッドの役割は、サービスコンテナバインディングの名前を返すことです。ユーザーがCacheファサードの任意の静的メソッドを参照すると、Laravelはサービスコンテナからcacheバインディングを解決し、そのオブジェクトに対して要求されたメソッド(この場合、get)を実行します。

リアルタイムファサード

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

  1. <?php
  2. namespace App\Models;
  3. use App\Contracts\Publisher;
  4. use Illuminate\Database\Eloquent\Model;
  5. class Podcast extends Model
  6. {
  7. /**
  8. * Publish the podcast.
  9. */
  10. public function publish(Publisher $publisher): void
  11. {
  12. $this->update(['publishing' => now()]);
  13. $publisher->publish($this);
  14. }
  15. }

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

  1. <?php
  2. namespace App\Models;
  3. use App\Contracts\Publisher;
  4. use Facades\App\Contracts\Publisher;
  5. use Illuminate\Database\Eloquent\Model;
  6. class Podcast extends Model
  7. {
  8. /**
  9. * Publish the podcast.
  10. */
  11. public function publish(Publisher $publisher): void
  12. public function publish(): void
  13. {
  14. $this->update(['publishing' => now()]);
  15. $publisher->publish($this);
  16. Publisher::publish($this);
  17. }
  18. }

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

  1. <?php
  2. use App\Models\Podcast;
  3. use Facades\App\Contracts\Publisher;
  4. use Illuminate\Foundation\Testing\RefreshDatabase;
  5. uses(RefreshDatabase::class);
  6. test('podcast can be published', function () {
  7. $podcast = Podcast::factory()->create();
  8. Publisher::shouldReceive('publish')->once()->with($podcast);
  9. $podcast->publish();
  10. });
  1. <?php
  2. namespace Tests\Feature;
  3. use App\Models\Podcast;
  4. use Facades\App\Contracts\Publisher;
  5. use Illuminate\Foundation\Testing\RefreshDatabase;
  6. use Tests\TestCase;
  7. class PodcastTest extends TestCase
  8. {
  9. use RefreshDatabase;
  10. /**
  11. * A test example.
  12. */
  13. public function test_podcast_can_be_published(): void
  14. {
  15. $podcast = Podcast::factory()->create();
  16. Publisher::shouldReceive('publish')->once()->with($podcast);
  17. $podcast->publish();
  18. }
  19. }

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

以下に、すべてのファサードとその基盤となるクラスを示します。これは、特定のファサードルートのAPIドキュメントを迅速に掘り下げるための便利なツールです。該当する場合は、サービスコンテナバインディングキーも含まれています。

ファサード クラス サービスコンテナバインディング
App Illuminate\Foundation\Application app
Artisan Illuminate\Contracts\Console\Kernel artisan
Auth (インスタンス) Illuminate\Contracts\Auth\Guard auth.driver
Auth Illuminate\Auth\AuthManager auth
Blade Illuminate\View\Compilers\BladeCompiler blade.compiler
Broadcast (インスタンス) Illuminate\Contracts\Broadcasting\Broadcaster
Broadcast Illuminate\Contracts\Broadcasting\Factory
Bus Illuminate\Contracts\Bus\Dispatcher
Cache (インスタンス) Illuminate\Cache\Repository cache.store
Cache Illuminate\Cache\CacheManager cache
Config Illuminate\Config\Repository config
Context Illuminate\Log\Context\Repository
Cookie Illuminate\Cookie\CookieJar cookie
Crypt Illuminate\Encryption\Encrypter encrypter
Date Illuminate\Support\DateFactory date
DB (インスタンス) Illuminate\Database\Connection db.connection
DB Illuminate\Database\DatabaseManager db
Event Illuminate\Events\Dispatcher events
Exceptions (インスタンス) Illuminate\Contracts\Debug\ExceptionHandler
Exceptions Illuminate\Foundation\Exceptions\Handler
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\PasswordBroker auth.password.broker
Password Illuminate\Auth\Passwords\PasswordBrokerManager auth.password
Pipeline (インスタンス) Illuminate\Pipeline\Pipeline
Process Illuminate\Process\Factory
Queue (ベースクラス) Illuminate\Queue\Queue
Queue (インスタンス) Illuminate\Contracts\Queue\Queue queue.connection
Queue Illuminate\Queue\QueueManager queue
RateLimiter Illuminate\Cache\RateLimiter
Redirect Illuminate\Routing\Redirector redirect
Redis (インスタンス) Illuminate\Redis\Connections\Connection redis.connection
Redis Illuminate\Redis\RedisManager redis
Request Illuminate\Http\Request request
Response (インスタンス) Illuminate\Http\Response
Response Illuminate\Contracts\Routing\ResponseFactory
Route Illuminate\Routing\Router router
Schedule Illuminate\Console\Scheduling\Schedule
Schema Illuminate\Database\Schema\Builder
Session (インスタンス) Illuminate\Session\Store session.store
Session Illuminate\Session\SessionManager session
Storage (インスタンス) Illuminate\Contracts\Filesystem\Filesystem filesystem.disk
Storage Illuminate\Filesystem\FilesystemManager filesystem
URL Illuminate\Routing\UrlGenerator url
Validator (インスタンス) Illuminate\Validation\Validator
Validator Illuminate\Validation\Factory validator
View (インスタンス) Illuminate\View\View
View Illuminate\View\Factory view
Vite Illuminate\Foundation\Vite