イントロダクションIntroduction
ファサードはアプリケーションのIoCコンテナに用意したクラスに「静的」なインターフェイスを提供してくれます。Laravelは多くのファサードを使用していますが、多分皆さんはご存じないまま使用されていることでしょう!Laravelの「ファサード(facade)」は、IoCコンテナー下で動作しているクラスに対し、"static proxies"として動作しています。これにより伝統的な静的メソッドよりも、簡潔で、テストの行いやすさと柔軟性を保ちながらも、記述的な書き方が行えます。Facades provide a "static" interface to classes that are available in the application's IoC container[/docs/4.2/ioc]. Laravel ships with many facades, and you have probably been using them without even knowing it! Laravel "facades" serve as "static proxies" to underlying classes in the IoC container, providing the benefit of a terse, expressive syntax while maintaining more testability and flexibility than traditional static methods.
自分のアプリケーションやパッケージでも時々ファサードを作成したくなると思います。ですからコンセプトと、開発方法、クラスの使い方を説明していきます。Occasionally, You may wish to create your own facades for your applications and packages, so let's explore the concept, development and usage of these classes.
**注目:**ファサードを学び始める前に、LaravelのIocコンテナに親しんでおくことを強くおすすめします。Note: Before digging into facades, it is strongly recommended that you become very familiar with the Laravel IoC container[/docs/4.2/ioc].
解説Explanation
Laravelアプリケーションに関する文脈では、ファサードはコンテナを通じてオブジェクトにアクセス方法を提供するクラスのことです。Facade
クラス中のメカニズムでこれを行なっています。Laravelのファサードと皆さんが作成したカスタムファサードは、Facade
クラスを拡張します。In the context of a Laravel application, a facade is a class that provides access to an object from the container. The machinery that makes this work is in the Facade
class. Laravel's facades, and any custom facades you create, will extend the base Facade
class.
ファサードクラスで実装する必要があるのはgetFacadeAccessor
だけです。getFacadeAccessor
メソッドの役目はコンテナを通じたインスタンスの解決に何を使用するかを定義することです。Facade
基本クラスは__callStatic()
マジックメソッドを使用し、あなたのファサードからの呼び出しをインスタンス化を解決したオブジェクトへと届けます。Your facade class only needs to implement a single method: getFacadeAccessor
. It's the getFacadeAccessor
method's job to define what to resolve from the container. The Facade
base class makes use of the __callStatic()
magic-method to defer calls from your facade to the resolved object.
Cache::get
のようにファサードの呼び出しが行われると、LaravelはIoCコンテナでCacheマネージャーを解決し、そのクラスのget
メソッドを呼び出します。技術的な言い方をすれば、Laravelのファサードは、サービスローケーターとしてのLaravelのIoCコンテナを使用した、使いやすい記法のことです。So, when you make a facade call like Cache::get
, Laravel resolves the Cache manager class out of the IoC container and calls the get
method on the class. In technical terms, Laravel Facades are a convenient syntax for using the Laravel IoC container as a service locator.
実際の使用Practical Usage
下の例では、Laravelのキャッシュシステムを呼び出しています。これを読むと、一見Cache
クラスのstaticなget
メソッドが呼び出されていのだと考えてしまうことでしょう。In the example below, a call is made to the Laravel cache system. By glancing at this code, one might assume that the static method get
is being called on the Cache
class.
$value = Cache::get('key');
ところが、Illuminate\Support\Facades\Cache
クラスを見てもらえば、staticのget
メソッドは存在していないことが分かります。However, if we look at that Illuminate\Support\Facades\Cache
class, you'll see that there is no static method get
:
class Cache extends Facade {
/**
* コンポーネントの登録名を取得する
*
* @return string
*/
protected static function getFacadeAccessor() { return 'cache'; }
}
Cacheクラスは基本のFacade
クラスを拡張し、getFacadeAccessor()
メソッドを定義しています。思い出してください。このメソッドの仕事はIoCで結合した名前をリターンすることでした。The Cache class extends the base Facade
class and defines a method getFacadeAccessor()
. Remember, this method's job is to return the name of an IoC binding.
ユーザーがCache
ファサードのどのstaticメソッドを利用しようと、LaravelはIoCコンテナからcache
に結び付けられたインスタンスを解決し、要求されたメソッドを(この場合はget
です)そのオブジェクトに対し実行します。When a user references any static method on the Cache
facade, Laravel resolves the cache
binding from the IoC container and runs the requested method (in this case, get
) against that object.
ですから、Cache::get
の呼び出しは以下のように書き直すこともできます。So, our Cache::get
call could be re-written like so:
$value = $app->make('cache')->get('key');
ファサードの作成Creating Facades
ファサードを作成するとアプリケーションやパッケージをシンプルにすることができます。必要なのは3つだけです。Creating a facade for your own application or package is simple. You only need 3 things:
- IoCでのバインディングAn IoC binding.
- ファサードクラスA facade class.
- ファサードエイリアスの設定A facade alias configuration.
例を見てください。PaymentGateway\Payment
クラスを定義しています。Let's look at an example. Here, we have a class defined as PaymentGateway\Payment
.
namespace PaymentGateway;
class Payment {
public function process()
{
//
}
}
このクラスはapp/models
ディレクトリーの中に設置されることでしょう。もしくは、Composerがオートロードできるディレクトリーの中に設置します。This class might live in your app/models
directory, or any other directory that Composer knows how to auto-load.
IoCコンテナでこのクラスのインスタンス化を解決することが必要です。では、バインディングを追加しましょう。We need to be able to resolve this class from the IoC container. So, let's add a binding:
App::bind('payment', function()
{
return new \PaymentGateway\Payment;
});
このバインディングコードを設置する良い場所は、新しいPaymentServiceProvider
という名前のサービスプロバイダーを作成し、register
メソッドにこのコードを追加します。それから、app/config/app.php
設定ファイルでこのサービスプロバイダーをLaravelがロードするように設定します。A great place to register this binding would be to create a new service provider[/docs/4.2/ioc#service-providers] named PaymentServiceProvider
, and add this binding to the register
method. You can then configure Laravel to load your service provider from the app/config/app.php
configuration file.
次に、ファサードクラスを作成しましょう。Next, we can create our own facade class:
use Illuminate\Support\Facades\Facade;
class Payment extends Facade {
protected static function getFacadeAccessor() { return 'payment'; }
}
最後に、お望みならば、app/config/app.php
設定ファイルのaliases
配列にファサードクラスのエイリアスを追加することもできます。これで、Payment
クラスのインスタンス上でprocess
メソッドを呼び出すことができます。Finally, if we wish, we can add an alias for our facade to the aliases
array in the app/config/app.php
configuration file. Now, we can call the process
method on an instance of the Payment
class.
Payment::process();
オートローディングエイリアスの注意点A Note On Auto-Loading Aliases
PHPが未定義のタイプヒントをオートロードしないため、aliases
配列中のクラスが、使用できない場合があります。もし、\ServiceWrapper\ApiTimeoutException
をApiTimeoutException
というエイリアス名で定義し、\ServiceWrapper
外の名前空間でcatch(ApiTimeoutException $e)
しても、投げられたその例外は捕捉されません。似たような問題は、エイリアスされたクラスへのタイプヒントを持つモデルでも、見かけられます。解決するには、そのようなエイリアスの参照に先立ち、それぞれのファイルの先頭で、必要なタイプヒントをuse
で指定しておく方法しかありません。Classes in the aliases
array are not available in some instances because PHP will not attempt to autoload undefined type-hinted classes[https://bugs.php.net/bug.php?id=39003]. If \ServiceWrapper\ApiTimeoutException
is aliased to ApiTimeoutException
, a catch(ApiTimeoutException $e)
outside of the namespace \ServiceWrapper
will never catch the exception, even if one is thrown. A similar problem is found in Models which have type hints to aliased classes. The only workaround is to forego aliasing and use
the classes you wish to type hint at the top of each file which requires them.
ファサードのモックMocking Facades
ファサードがどうしてこのように動作するのかという理由の重要な一面が、ユニットテストです。実際、ファサードが存在している一番大きな理由がテストの行いやすさです。詳細はドキュメントのファサードのモックの章をご覧ください。Unit testing is an important aspect of why facades work the way that they do. In fact, testability is the primary reason for facades to even exist. For more information, check out the mocking facades[/docs/4.2/testing#mocking-facades] section of the documentation.
ファサードクラス一覧Facade Class Reference
以下は全ファサードと、実際のクラスの一覧です。これは特定のファサードを元にし、APIドキュメントを素早く探したい場合に便利な道具になります。IoC結合キーも含んでいますので、応用して下さい。Below you will find every facade and its underlying class. This is a useful tool for quickly digging into the API documentation for a given facade root. The IoC binding[/docs/4.2/ioc] key is also included where applicable.
ファサードFacade | クラスClass | IoC結合IoC Binding |
---|---|---|
AppApp | Illuminate\Foundation\ApplicationIlluminate\Foundation\Application[http://laravel.com/api/4.2/Illuminate/Foundation/Application.html] | app app |
ArtisanArtisan | Illuminate\Console\ApplicationIlluminate\Console\Application[http://laravel.com/api/4.2/Illuminate/Console/Application.html] | artisan artisan |
AuthAuth | Illuminate\Auth\AuthManagerIlluminate\Auth\AuthManager[http://laravel.com/api/4.2/Illuminate/Auth/AuthManager.html] | auth auth |
Auth (インスタンス)Auth (Instance) | Illuminate\Auth\GuardIlluminate\Auth\Guard[http://laravel.com/api/4.2/Illuminate/Auth/Guard.html] | |
BladeBlade | Illuminate\View\Compilers\BladeCompilerIlluminate\View\Compilers\BladeCompiler[http://laravel.com/api/4.2/Illuminate/View/Compilers/BladeCompiler.html] | blade.compiler blade.compiler |
CacheCache | Illuminate\Cache\RepositoryIlluminate\Cache\Repository[http://laravel.com/api/4.2/Illuminate/Cache/Repository.html] | cache cache |
ConfigConfig | Illuminate\Config\RepositoryIlluminate\Config\Repository[http://laravel.com/api/4.2/Illuminate/Config/Repository.html] | config config |
CookieCookie | Illuminate\Cookie\CookieJarIlluminate\Cookie\CookieJar[http://laravel.com/api/4.2/Illuminate/Cookie/CookieJar.html] | cookie cookie |
CryptCrypt | Illuminate\Encryption\EncrypterIlluminate\Encryption\Encrypter[http://laravel.com/api/4.2/Illuminate/Encryption/Encrypter.html] | encrypter encrypter |
DBDB | Illuminate\Database\DatabaseManagerIlluminate\Database\DatabaseManager[http://laravel.com/api/4.2/Illuminate/Database/DatabaseManager.html] | db db |
DB (インスタンス)DB (Instance) | Illuminate\Database\ConnectionIlluminate\Database\Connection[http://laravel.com/api/4.2/Illuminate/Database/Connection.html] | |
EventEvent | Illuminate\Events\DispatcherIlluminate\Events\Dispatcher[http://laravel.com/api/4.2/Illuminate/Events/Dispatcher.html] | events events |
FileFile | Illuminate\Filesystem\FilesystemIlluminate\Filesystem\Filesystem[http://laravel.com/api/4.2/Illuminate/Filesystem/Filesystem.html] | files files |
FormForm | Illuminate\Html\FormBuilderIlluminate\Html\FormBuilder[http://laravel.com/api/4.2/Illuminate/Html/FormBuilder.html] | form form |
HashHash | Illuminate\Hashing\HasherInterfaceIlluminate\Hashing\HasherInterface[http://laravel.com/api/4.2/Illuminate/Hashing/HasherInterface.html] | hash hash |
HTMLHTML | Illuminate\Html\HtmlBuilderIlluminate\Html\HtmlBuilder[http://laravel.com/api/4.2/Illuminate/Html/HtmlBuilder.html] | html html |
InputInput | Illuminate\Http\RequestIlluminate\Http\Request[http://laravel.com/api/4.2/Illuminate/Http/Request.html] | request request |
LangLang | Illuminate\Translation\TranslatorIlluminate\Translation\Translator[http://laravel.com/api/4.2/Illuminate/Translation/Translator.html] | translator translator |
LogLog | Illuminate\Log\WriterIlluminate\Log\Writer[http://laravel.com/api/4.2/Illuminate/Log/Writer.html] | log log |
MailMail | Illuminate\Mail\MailerIlluminate\Mail\Mailer[http://laravel.com/api/4.2/Illuminate/Mail/Mailer.html] | mailer mailer |
PaginatorPaginator | Illuminate\Pagination\FactoryIlluminate\Pagination\Factory[http://laravel.com/api/4.2/Illuminate/Pagination/Factory.html] | paginator paginator |
Paginator (インスタンス)Paginator (Instance) | Illuminate\Pagination\PaginatorIlluminate\Pagination\Paginator[http://laravel.com/api/4.2/Illuminate/Pagination/Paginator.html] | |
PasswordPassword | Illuminate\Auth\Reminders\PasswordBrokerIlluminate\Auth\Reminders\PasswordBroker[http://laravel.com/api/4.2/Illuminate/Auth/Reminders/PasswordBroker.html] | auth.reminder auth.reminder |
QueueQueue | Illuminate\Queue\QueueManagerIlluminate\Queue\QueueManager[http://laravel.com/api/4.2/Illuminate/Queue/QueueManager.html] | queue queue |
Queue (インスタンス)Queue (Instance) | Illuminate\Queue\QueueInterfaceIlluminate\Queue\QueueInterface[http://laravel.com/api/4.2/Illuminate/Queue/QueueInterface.html] | |
Queue (ベースクラス)Queue (Base Class) | Illuminate\Queue\QueueIlluminate\Queue\Queue[http://laravel.com/api/4.2/Illuminate/Queue/Queue.html] | |
RedirectRedirect | Illuminate\Routing\RedirectorIlluminate\Routing\Redirector[http://laravel.com/api/4.2/Illuminate/Routing/Redirector.html] | redirect redirect |
RedisRedis | Illuminate\Redis\DatabaseIlluminate\Redis\Database[http://laravel.com/api/4.2/Illuminate/Redis/Database.html] | redis redis |
RequestRequest | Illuminate\Http\RequestIlluminate\Http\Request[http://laravel.com/api/4.2/Illuminate/Http/Request.html] | request request |
ResponseResponse | Illuminate\Support\Facades\ResponseIlluminate\Support\Facades\Response[http://laravel.com/api/4.2/Illuminate/Support/Facades/Response.html] | |
RouteRoute | Illuminate\Routing\RouterIlluminate\Routing\Router[http://laravel.com/api/4.2/Illuminate/Routing/Router.html] | router router |
SchemaSchema | Illuminate\Database\Schema\BlueprintIlluminate\Database\Schema\Blueprint[http://laravel.com/api/4.2/Illuminate/Database/Schema/Blueprint.html] | |
SessionSession | Illuminate\Session\SessionManagerIlluminate\Session\SessionManager[http://laravel.com/api/4.2/Illuminate/Session/SessionManager.html] | session session |
Session (インスタンス)Session (Instance) | Illuminate\Session\StoreIlluminate\Session\Store[http://laravel.com/api/4.2/Illuminate/Session/Store.html] | |
SSHSSH | Illuminate\Remote\RemoteManagerIlluminate\Remote\RemoteManager[http://laravel.com/api/4.2/Illuminate/Remote/RemoteManager.html] | remote remote |
SSH (インスタンス)SSH (Instance) | Illuminate\Remote\ConnectionIlluminate\Remote\Connection[http://laravel.com/api/4.2/Illuminate/Remote/Connection.html] | |
URLURL | Illuminate\Routing\UrlGeneratorIlluminate\Routing\UrlGenerator[http://laravel.com/api/4.2/Illuminate/Routing/UrlGenerator.html] | url url |
ValidatorValidator | Illuminate\Validation\FactoryIlluminate\Validation\Factory[http://laravel.com/api/4.2/Illuminate/Validation/Factory.html] | validator validator |
Validator (インスタンス)Validator (Instance) | Illuminate\Validation\ValidatorIlluminate\Validation\Validator[http://laravel.com/api/4.2/Illuminate/Validation/Validator.html] | |
ViewView | Illuminate\View\FactoryIlluminate\View\Factory[http://laravel.com/api/4.2/Illuminate/View/Factory.html] | view view |
View (インスタンス)View (Instance) | Illuminate\View\ViewIlluminate\View\View[http://laravel.com/api/4.2/Illuminate/View/View.html] |